home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.5 Applications 2004 May / SGI IRIX 6.5 Applications 2004 May.iso / dist / java3d.idb / usr / demos / java / j3d / programs / examples / FourByFour / Board.java.z / Board.java
Encoding:
Java Source  |  2003-08-08  |  87.7 KB  |  2,306 lines

  1. /*
  2.  *    @(#)Board.java 1.10 02/04/01 15:03:29
  3.  *
  4.  * Copyright (c) 1996-2002 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  *
  10.  * - Redistributions of source code must retain the above copyright
  11.  *   notice, this list of conditions and the following disclaimer.
  12.  *
  13.  * - Redistribution in binary form must reproduce the above copyright
  14.  *   notice, this list of conditions and the following disclaimer in
  15.  *   the documentation and/or other materials provided with the
  16.  *   distribution.
  17.  *
  18.  * Neither the name of Sun Microsystems, Inc. or the names of
  19.  * contributors may be used to endorse or promote products derived
  20.  * from this software without specific prior written permission.
  21.  *
  22.  * This software is provided "AS IS," without a warranty of any
  23.  * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
  24.  * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
  25.  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
  26.  * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
  27.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  28.  * DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
  29.  * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
  30.  * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
  31.  * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
  32.  * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE,
  33.  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  34.  *
  35.  * You acknowledge that Software is not designed,licensed or intended
  36.  * for use in the design, construction, operation or maintenance of
  37.  * any nuclear facility.
  38.  */
  39.  
  40. import java.awt.*;
  41.  
  42. /**
  43.  *  Class:       Board
  44.  *
  45.  *  Description: Handles all logic with respect to play. Also renders
  46.  *               the 2D window.
  47.  *
  48.  *  Version:     1.1
  49.  *
  50.  */
  51. class Board {
  52.  
  53.    final static int UNOCCUPIED = 0;
  54.    final static int HUMAN      = 1;
  55.    final static int MACHINE    = 2;
  56.    final static int END        = 3;
  57.  
  58.    private int[]      moves;
  59.    private int[]      occupied;
  60.    private int[][]    combinations;
  61.    private int[][]    outside_four;
  62.    private int[][]    inside_four;
  63.    private int[][]    faces;
  64.    private int[][]    pos_to_comb;
  65.    private int[][]    best_picks;
  66.    private int        num_points;
  67.    private int        num_balls;
  68.    private int        num_polygons;
  69.    private int        num_pt_indexes;
  70.    private int        num_normal_indexes;
  71.    private int        pt_start;
  72.    private int        color_index;
  73.    private int        width;
  74.    private int        height;
  75.    private int        center_x;
  76.    private int        center_y;
  77.    private int        player;
  78.    private int        skill_level;
  79.    private int        outside_four_index;
  80.    private int        inside_four_index;
  81.    private int        face_index;
  82.    private int        nmoves;
  83.    private int        current_face;
  84.    private int        min = 1000;
  85.    private int        max = 0;
  86.    private long[]     sort_array;
  87.    private long       time;
  88.    private long       beg_time;
  89.    private long       end_time;
  90.    private Color[]    color_ramp;
  91.    private Color      background;
  92.    private Color      label_color;
  93.    private Color      red;
  94.    private Color      blue;
  95.    private Color      white;
  96.    private Color      gray;
  97.    private Color      yellow;
  98.    private double     max_dist;
  99.    private FourByFour panel;
  100.    private boolean    debug;
  101.    private boolean    outside_four_flag;
  102.    private boolean    inside_four_flag;
  103.    private boolean    face_flag;
  104.    private boolean    label_flag;
  105.    private boolean    block_chair_flag;
  106.    private boolean    undoFlag;
  107.    private boolean[]  highlight;
  108.    private int        block_chair_next_move;
  109.    private int        block_chair_face;
  110.    private Positions  positions;
  111.    private Canvas2D   canvas;
  112.  
  113.    Board (FourByFour panel, Positions positions, int width, int height) {
  114.  
  115.       // Set the debug state.
  116.       debug = false;
  117.  
  118.       // Store arguments
  119.       this.width = width;
  120.       this.height = height;
  121.       this.panel = panel;
  122.       this.positions = positions;
  123.  
  124.       // Initialize flags
  125.       label_flag = false;
  126.       outside_four_flag = false;
  127.       inside_four_flag = false;
  128.       block_chair_flag = false;
  129.       undoFlag = false;
  130.  
  131.       // Total number of board positions.
  132.       num_points = 64;
  133.  
  134.       // Allocate the logic arrays.
  135.       moves = new int[64];
  136.       occupied = new int[64];
  137.       combinations = new int[76][7];
  138.       outside_four = new int[18][6];
  139.       inside_four = new int[18][6];
  140.       faces = new int[18][18];
  141.       pos_to_comb = new int[64][8];
  142.       best_picks = new int[64][8];
  143.       highlight = new boolean[18];
  144.  
  145.       // Initialize the logic arrays.
  146.       init_combinations();
  147.       init_faces();
  148.       init_outside_four();
  149.       init_inside_four();
  150.  
  151.       // Set the player with the first move. 
  152.       player = HUMAN;
  153.  
  154.       // Set the default skill level.
  155.       skill_level = 4;
  156.  
  157.       // Initialize the number of moves.
  158.       nmoves = 0;
  159.  
  160.       // Define colors
  161.       background = new Color(13, 13, 51);
  162.       red = new Color(230, 26, 51);
  163.       blue = new Color(51, 51, 230);
  164.       white = new Color(255, 255, 255);
  165.       gray = new Color(240, 240, 240);
  166.       yellow = new Color(240, 240, 0);
  167.  
  168.       // Record the start time
  169.       beg_time = System.currentTimeMillis();
  170.    }
  171.  
  172.    public void setCanvas(Canvas2D canvas) {
  173.       this.canvas = canvas;
  174.    }
  175.  
  176.    public void init_combinations () {
  177.  
  178.       // The combination array contains all possible winning combinations.
  179.       //
  180.       // Each combination has the following format:
  181.       //
  182.       // combinations[x][0] =  status: 0      = no player has selected positons in this row
  183.       //                              -1      = both players have men in this row
  184.       //                               1 to 4 = number of positions occupied by player
  185.       //
  186.       // combinations[x][1] =  player who owns this row (valid only if status = 1-4)
  187.       // combinations[x][2] =  postion that define the row 
  188.       // combinations[x][3] =  postion that define the row 
  189.       // combinations[x][4] =  postion that define the row 
  190.       // combinations[x][5] =  postion that define the row 
  191.  
  192.       // Horizontal, Z
  193.  
  194.       combinations[ 0][0] =  0;  combinations[ 1][0] =  0;  combinations[ 2][0] =  0;  combinations[ 3][0] =  0;
  195.       combinations[ 0][1] =  0;  combinations[ 1][1] =  0;  combinations[ 2][1] =  0;  combinations[ 3][1] =  0;
  196.       combinations[ 0][2] =  0;  combinations[ 1][2] =  4;  combinations[ 2][2] =  8;  combinations[ 3][2] = 12;
  197.       combinations[ 0][3] =  1;  combinations[ 1][3] =  5;  combinations[ 2][3] =  9;  combinations[ 3][3] = 13;
  198.       combinations[ 0][4] =  2;  combinations[ 1][4] =  6;  combinations[ 2][4] = 10;  combinations[ 3][4] = 14;
  199.       combinations[ 0][5] =  3;  combinations[ 1][5] =  7;  combinations[ 2][5] = 11;  combinations[ 3][5] = 15;
  200.  
  201.       combinations[ 4][0] =  0;  combinations[ 5][0] =  0;  combinations[ 6][0] =  0;  combinations[ 7][0] =  0;
  202.       combinations[ 4][1] =  0;  combinations[ 5][1] =  0;  combinations[ 6][1] =  0;  combinations[ 7][1] =  0;
  203.       combinations[ 4][2] = 16;  combinations[ 5][2] = 20;  combinations[ 6][2] = 24;  combinations[ 7][2] = 28;
  204.       combinations[ 4][3] = 17;  combinations[ 5][3] = 21;  combinations[ 6][3] = 25;  combinations[ 7][3] = 29;
  205.       combinations[ 4][4] = 18;  combinations[ 5][4] = 22;  combinations[ 6][4] = 26;  combinations[ 7][4] = 30;
  206.       combinations[ 4][5] = 19;  combinations[ 5][5] = 23;  combinations[ 6][5] = 27;  combinations[ 7][5] = 31;
  207.  
  208.       combinations[ 8][0] =  0;  combinations[ 9][0] =  0;  combinations[10][0] =  0;  combinations[11][0] =  0;
  209.       combinations[ 8][1] =  0;  combinations[ 9][1] =  0;  combinations[10][1] =  0;  combinations[11][1] =  0;
  210.       combinations[ 8][2] = 32;  combinations[ 9][2] = 36;  combinations[10][2] = 40;  combinations[11][2] = 44;
  211.       combinations[ 8][3] = 33;  combinations[ 9][3] = 37;  combinations[10][3] = 41;  combinations[11][3] = 45;
  212.       combinations[ 8][4] = 34;  combinations[ 9][4] = 38;  combinations[10][4] = 42;  combinations[11][4] = 46;
  213.       combinations[ 8][5] = 35;  combinations[ 9][5] = 39;  combinations[10][5] = 43;  combinations[11][5] = 47;
  214.  
  215.       combinations[12][0] =  0;  combinations[13][0] =  0;  combinations[14][0] =  0;  combinations[15][0] =  0;
  216.       combinations[12][1] =  0;  combinations[13][1] =  0;  combinations[14][1] =  0;  combinations[15][1] =  0;
  217.       combinations[12][2] = 48;  combinations[13][2] = 52;  combinations[14][2] = 56;  combinations[15][2] = 60;
  218.       combinations[12][3] = 49;  combinations[13][3] = 53;  combinations[14][3] = 57;  combinations[15][3] = 61;
  219.       combinations[12][4] = 50;  combinations[13][4] = 54;  combinations[14][4] = 58;  combinations[15][4] = 62;
  220.       combinations[12][5] = 51;  combinations[13][5] = 55;  combinations[14][5] = 59;  combinations[15][5] = 63;
  221.  
  222.       // Vertical, Z
  223.  
  224.       combinations[16][0] =  0;  combinations[17][0] =  0;  combinations[18][0] =  0;  combinations[19][0] =  0;
  225.       combinations[16][1] =  0;  combinations[17][1] =  0;  combinations[18][1] =  0;  combinations[19][1] =  0;
  226.       combinations[16][2] =  0;  combinations[17][2] =  1;  combinations[18][2] =  2;  combinations[19][2] =  3;
  227.       combinations[16][3] =  4;  combinations[17][3] =  5;  combinations[18][3] =  6;  combinations[19][3] =  7;
  228.       combinations[16][4] =  8;  combinations[17][4] =  9;  combinations[18][4] = 10;  combinations[19][4] = 11;
  229.       combinations[16][5] = 12;  combinations[17][5] = 13;  combinations[18][5] = 14;  combinations[19][5] = 15;
  230.  
  231.       combinations[20][0] =  0;  combinations[21][0] =  0;  combinations[22][0] =  0;  combinations[23][0] =  0;
  232.       combinations[20][1] =  0;  combinations[21][1] =  0;  combinations[22][1] =  0;  combinations[23][1] =  0;
  233.       combinations[20][2] = 16;  combinations[21][2] = 17;  combinations[22][2] = 18;  combinations[23][2] = 19;
  234.       combinations[20][3] = 20;  combinations[21][3] = 21;  combinations[22][3] = 22;  combinations[23][3] = 23;
  235.       combinations[20][4] = 24;  combinations[21][4] = 25;  combinations[22][4] = 26;  combinations[23][4] = 27;
  236.       combinations[20][5] = 28;  combinations[21][5] = 29;  combinations[22][5] = 30;  combinations[23][5] = 31;
  237.  
  238.       combinations[24][0] =  0;  combinations[25][0] =  0;  combinations[26][0] =  0;  combinations[27][0] =  0;
  239.       combinations[24][1] =  0;  combinations[25][1] =  0;  combinations[26][1] =  0;  combinations[27][1] =  0;
  240.       combinations[24][2] = 32;  combinations[25][2] = 33;  combinations[26][2] = 34;  combinations[27][2] = 35;
  241.       combinations[24][3] = 36;  combinations[25][3] = 37;  combinations[26][3] = 38;  combinations[27][3] = 39;
  242.       combinations[24][4] = 40;  combinations[25][4] = 41;  combinations[26][4] = 42;  combinations[27][4] = 43;
  243.       combinations[24][5] = 44;  combinations[25][5] = 45;  combinations[26][5] = 46;  combinations[27][5] = 47;
  244.  
  245.       combinations[28][0] =  0;  combinations[29][0] =  0;  combinations[30][0] =  0;  combinations[31][0] =  0;
  246.       combinations[28][1] =  0;  combinations[29][1] =  0;  combinations[30][1] =  0;  combinations[31][1] =  0;
  247.       combinations[28][2] = 48;  combinations[29][2] = 49;  combinations[30][2] = 50;  combinations[31][2] = 51;
  248.       combinations[28][3] = 52;  combinations[29][3] = 53;  combinations[30][3] = 54;  combinations[31][3] = 55;
  249.       combinations[28][4] = 56;  combinations[29][4] = 57;  combinations[30][4] = 58;  combinations[31][4] = 59;
  250.       combinations[28][5] = 60;  combinations[29][5] = 61;  combinations[30][5] = 62;  combinations[31][5] = 63;
  251.  
  252.       // Diagonal, Z
  253.  
  254.       combinations[32][0] =  0;  combinations[33][0] =  0;  combinations[34][0] =  0;  combinations[35][0] =  0;
  255.       combinations[32][1] =  0;  combinations[33][1] =  0;  combinations[34][1] =  0;  combinations[35][1] =  0;
  256.       combinations[32][2] =  0;  combinations[33][2] = 16;  combinations[34][2] = 32;  combinations[35][2] = 48;
  257.       combinations[32][3] =  5;  combinations[33][3] = 21;  combinations[34][3] = 37;  combinations[35][3] = 53;
  258.       combinations[32][4] = 10;  combinations[33][4] = 26;  combinations[34][4] = 42;  combinations[35][4] = 58;
  259.       combinations[32][5] = 15;  combinations[33][5] = 31;  combinations[34][5] = 47;  combinations[35][5] = 63;
  260.  
  261.       combinations[36][0] =  0;  combinations[37][0] =  0;  combinations[38][0] =  0;  combinations[39][0] =  0;
  262.       combinations[36][1] =  0;  combinations[37][1] =  0;  combinations[38][1] =  0;  combinations[39][1] =  0;
  263.       combinations[36][2] =  3;  combinations[37][2] = 19;  combinations[38][2] = 35;  combinations[39][2] = 51;
  264.       combinations[36][3] =  6;  combinations[37][3] = 22;  combinations[38][3] = 38;  combinations[39][3] = 54;
  265.       combinations[36][4] =  9;  combinations[37][4] = 25;  combinations[38][4] = 41;  combinations[39][4] = 57;
  266.       combinations[36][5] = 12;  combinations[37][5] = 28;  combinations[38][5] = 44;  combinations[39][5] = 60;
  267.  
  268.       // Horizontal, X
  269.  
  270.       combinations[40][0] =  0;  combinations[41][0] =  0;  combinations[42][0] =  0;  combinations[43][0] =  0;
  271.       combinations[40][1] =  0;  combinations[41][1] =  0;  combinations[42][1] =  0;  combinations[43][1] =  0;
  272.       combinations[40][2] = 51;  combinations[41][2] = 55;  combinations[42][2] = 59;  combinations[43][2] = 63;
  273.       combinations[40][3] = 35;  combinations[41][3] = 39;  combinations[42][3] = 43;  combinations[43][3] = 47;
  274.       combinations[40][4] = 19;  combinations[41][4] = 23;  combinations[42][4] = 27;  combinations[43][4] = 31;
  275.       combinations[40][5] =  3;  combinations[41][5] =  7;  combinations[42][5] = 11;  combinations[43][5] = 15;
  276.  
  277.       combinations[44][0] =  0;  combinations[45][0] =  0;  combinations[46][0] =  0;  combinations[47][0] =  0;
  278.       combinations[44][1] =  0;  combinations[45][1] =  0;  combinations[46][1] =  0;  combinations[47][1] =  0;
  279.       combinations[44][2] = 50;  combinations[45][2] = 54;  combinations[46][2] = 58;  combinations[47][2] = 62;
  280.       combinations[44][3] = 34;  combinations[45][3] = 38;  combinations[46][3] = 42;  combinations[47][3] = 46;
  281.       combinations[44][4] = 18;  combinations[45][4] = 22;  combinations[46][4] = 26;  combinations[47][4] = 30;
  282.       combinations[44][5] =  2;  combinations[45][5] =  6;  combinations[46][5] = 10;  combinations[47][5] = 14;
  283.  
  284.       combinations[48][0] =  0;  combinations[49][0] =  0;  combinations[50][0] =  0;  combinations[51][0] =  0;
  285.       combinations[48][1] =  0;  combinations[49][1] =  0;  combinations[50][1] =  0;  combinations[51][1] =  0;
  286.       combinations[48][2] = 49;  combinations[49][2] = 53;  combinations[50][2] = 57;  combinations[51][2] = 61;
  287.       combinations[48][3] = 33;  combinations[49][3] = 37;  combinations[50][3] = 41;  combinations[51][3] = 45;
  288.       combinations[48][4] = 17;  combinations[49][4] = 21;  combinations[50][4] = 25;  combinations[51][4] = 29;
  289.       combinations[48][5] =  1;  combinations[49][5] =  5;  combinations[50][5] =  9;  combinations[51][5] = 13;
  290.  
  291.       combinations[52][0] =  0;  combinations[53][0] =  0;  combinations[54][0] =  0;  combinations[55][0] =  0;
  292.       combinations[52][1] =  0;  combinations[53][1] =  0;  combinations[54][1] =  0;  combinations[55][1] =  0;
  293.       combinations[52][2] = 48;  combinations[53][2] = 52;  combinations[54][2] = 56;  combinations[55][2] = 60;
  294.       combinations[52][3] = 32;  combinations[53][3] = 36;  combinations[54][3] = 40;  combinations[55][3] = 44;
  295.       combinations[52][4] = 16;  combinations[53][4] = 20;  combinations[54][4] = 24;  combinations[55][4] = 28;
  296.       combinations[52][5] =  0;  combinations[53][5] =  4;  combinations[54][5] =  8;  combinations[55][5] = 12;
  297.  
  298.       // Diagonal, X
  299.  
  300.       combinations[56][0] =  0;  combinations[57][0] =  0;  combinations[58][0] =  0;  combinations[59][0] =  0;
  301.       combinations[56][1] =  0;  combinations[57][1] =  0;  combinations[58][1] =  0;  combinations[59][1] =  0;
  302.       combinations[56][2] = 51;  combinations[57][2] = 50;  combinations[58][2] = 49;  combinations[59][2] = 48;
  303.       combinations[56][3] = 39;  combinations[57][3] = 38;  combinations[58][3] = 37;  combinations[59][3] = 36;
  304.       combinations[56][4] = 27;  combinations[57][4] = 26;  combinations[58][4] = 25;  combinations[59][4] = 24;
  305.       combinations[56][5] = 15;  combinations[57][5] = 14;  combinations[58][5] = 13;  combinations[59][5] = 12;
  306.  
  307.       combinations[60][0] =  0;  combinations[61][0] =  0;  combinations[62][0] =  0;  combinations[63][0] =  0;
  308.       combinations[60][1] =  0;  combinations[61][1] =  0;  combinations[62][1] =  0;  combinations[63][1] =  0;
  309.       combinations[60][2] =  3;  combinations[61][2] =  2;  combinations[62][2] =  1;  combinations[63][2] =  0;
  310.       combinations[60][3] = 23;  combinations[61][3] = 22;  combinations[62][3] = 21;  combinations[63][3] = 20;
  311.       combinations[60][4] = 43;  combinations[61][4] = 42;  combinations[62][4] = 41;  combinations[63][4] = 40;
  312.       combinations[60][5] = 63;  combinations[61][5] = 62;  combinations[62][5] = 61;  combinations[63][5] = 60;
  313.  
  314.       // Diagonal, Y
  315.  
  316.       combinations[64][0] =  0;  combinations[65][0] =  0;  combinations[66][0] =  0;  combinations[67][0] =  0;
  317.       combinations[64][1] =  0;  combinations[65][1] =  0;  combinations[66][1] =  0;  combinations[67][1] =  0;
  318.       combinations[64][2] = 63;  combinations[65][2] = 59;  combinations[66][2] = 55;  combinations[67][2] = 51;
  319.       combinations[64][3] = 46;  combinations[65][3] = 42;  combinations[66][3] = 38;  combinations[67][3] = 34;
  320.       combinations[64][4] = 29;  combinations[65][4] = 25;  combinations[66][4] = 21;  combinations[67][4] = 17;
  321.       combinations[64][5] = 12;  combinations[65][5] =  8;  combinations[66][5] =  4;  combinations[67][5] =  0;
  322.  
  323.       combinations[68][0] =  0;  combinations[69][0] =  0;  combinations[70][0] =  0;  combinations[71][0] =  0;
  324.       combinations[68][1] =  0;  combinations[69][1] =  0;  combinations[70][1] =  0;  combinations[71][1] =  0;
  325.       combinations[68][2] = 15;  combinations[69][2] = 11;  combinations[70][2] =  7;  combinations[71][2] =  3;
  326.       combinations[68][3] = 30;  combinations[69][3] = 26;  combinations[70][3] = 22;  combinations[71][3] = 18;
  327.       combinations[68][4] = 45;  combinations[69][4] = 41;  combinations[70][4] = 37;  combinations[71][4] = 33;
  328.       combinations[68][5] = 60;  combinations[69][5] = 56;  combinations[70][5] = 52;  combinations[71][5] = 48;
  329.  
  330.       // Corner to Corner
  331.  
  332.       combinations[72][0] =  0;  combinations[73][0] =  0;  combinations[74][0] =  0;  combinations[75][0] =  0;
  333.       combinations[72][1] =  0;  combinations[73][1] =  0;  combinations[74][1] =  0;  combinations[75][1] =  0;
  334.       combinations[72][2] =  0;  combinations[73][2] =  3;  combinations[74][2] = 12;  combinations[75][2] = 15;
  335.       combinations[72][3] = 21;  combinations[73][3] = 22;  combinations[74][3] = 25;  combinations[75][3] = 26;
  336.       combinations[72][4] = 42;  combinations[73][4] = 41;  combinations[74][4] = 38;  combinations[75][4] = 37;
  337.       combinations[72][5] = 63;  combinations[73][5] = 60;  combinations[74][5] = 51;  combinations[75][5] = 48;
  338.  
  339.       // Initialize the combination flags to zero.
  340.       for (int i=0; i<76; i++) 
  341.          combinations[i][6] = 0;
  342.  
  343.       // Set up the pos_to_comb array to point to every winning combination that a given 
  344.       // position may have.
  345.       setup_pos_to_comb();
  346.  
  347.       // Set up the best_picks array.
  348.       update_best_picks();
  349.    }
  350.  
  351.  
  352.   /**
  353.    *  Initialize the "outside four" array. 
  354.    */
  355.    public void init_outside_four() {
  356.       for (int i=0; i<18; i++) {
  357.          outside_four[i][0] = 0;
  358.          outside_four[i][1] = 0;
  359.          outside_four[i][2] = faces[i][ 2];
  360.          outside_four[i][3] = faces[i][ 5];
  361.          outside_four[i][4] = faces[i][14];
  362.          outside_four[i][5] = faces[i][17];
  363.       }
  364.    }
  365.  
  366.  
  367.   /**
  368.    *  Initialize the "inside four" array.
  369.    */
  370.    public void init_inside_four() {
  371.       for (int i=0; i<18; i++) {
  372.          inside_four[i][0] = 0;
  373.          inside_four[i][1] = 0;
  374.          inside_four[i][2] = faces[i][ 7];
  375.          inside_four[i][3] = faces[i][ 8];
  376.          inside_four[i][4] = faces[i][11];
  377.          inside_four[i][5] = faces[i][12];
  378.       }
  379.    }
  380.  
  381.   /**
  382.    *  Initialize the "faces" array. 
  383.    */
  384.    public void init_faces () {
  385.  
  386.       faces[ 0][ 0] =  0;
  387.       faces[ 0][ 1] =  0;
  388.       faces[ 0][ 2] = 12;  faces[ 0][ 6] = 13;  faces[ 0][10] = 14;  faces[ 0][14] = 15;
  389.       faces[ 0][ 3] =  8;  faces[ 0][ 7] =  9;  faces[ 0][11] = 10;  faces[ 0][15] = 11;
  390.       faces[ 0][ 4] =  4;  faces[ 0][ 8] =  5;  faces[ 0][12] =  6;  faces[ 0][16] =  7;
  391.       faces[ 0][ 5] =  0;  faces[ 0][ 9] =  1;  faces[ 0][13] =  2;  faces[ 0][17] =  3;
  392.  
  393.       faces[ 1][ 0] =  0;
  394.       faces[ 1][ 1] =  0;
  395.       faces[ 1][ 2] = 28;  faces[ 1][ 6] = 29;  faces[ 1][10] = 30;  faces[ 1][14] = 31;
  396.       faces[ 1][ 3] = 24;  faces[ 1][ 7] = 25;  faces[ 1][11] = 26;  faces[ 1][15] = 27;
  397.       faces[ 1][ 4] = 20;  faces[ 1][ 8] = 21;  faces[ 1][12] = 22;  faces[ 1][16] = 23;
  398.       faces[ 1][ 5] = 16;  faces[ 1][ 9] = 17;  faces[ 1][13] = 18;  faces[ 1][17] = 19;
  399.  
  400.       faces[ 2][ 0] =  0;
  401.       faces[ 2][ 1] =  0;
  402.       faces[ 2][ 2] = 44;  faces[ 2][ 6] = 45;  faces[ 2][10] = 46;  faces[ 2][14] = 47;
  403.       faces[ 2][ 3] = 40;  faces[ 2][ 7] = 41;  faces[ 2][11] = 42;  faces[ 2][15] = 43;
  404.       faces[ 2][ 4] = 36;  faces[ 2][ 8] = 37;  faces[ 2][12] = 38;  faces[ 2][16] = 39;
  405.       faces[ 2][ 5] = 32;  faces[ 2][ 9] = 33;  faces[ 2][13] = 34;  faces[ 2][17] = 35;
  406.  
  407.       faces[ 3][ 0] =  0;
  408.       faces[ 3][ 1] =  0;
  409.       faces[ 3][ 2] = 60;  faces[ 3][ 6] = 61;  faces[ 3][10] = 62;  faces[ 3][14] = 63;
  410.       faces[ 3][ 3] = 56;  faces[ 3][ 7] = 57;  faces[ 3][11] = 58;  faces[ 3][15] = 59;
  411.       faces[ 3][ 4] = 52;  faces[ 3][ 8] = 53;  faces[ 3][12] = 54;  faces[ 3][16] = 55;
  412.       faces[ 3][ 5] = 48;  faces[ 3][ 9] = 49;  faces[ 3][13] = 50;  faces[ 3][17] = 51;
  413.  
  414.       faces[ 4][ 0] =  0;
  415.       faces[ 4][ 1] =  0;
  416.       faces[ 4][ 2] = 12;  faces[ 4][ 6] = 28;  faces[ 4][10] = 44;  faces[ 4][14] = 60;
  417.       faces[ 4][ 3] =  8;  faces[ 4][ 7] = 24;  faces[ 4][11] = 40;  faces[ 4][15] = 56;
  418.       faces[ 4][ 4] =  4;  faces[ 4][ 8] = 20;  faces[ 4][12] = 36;  faces[ 4][16] = 52;
  419.       faces[ 4][ 5] =  0;  faces[ 4][ 9] = 16;  faces[ 4][13] = 32;  faces[ 4][17] = 48;
  420.  
  421.       faces[ 5][ 0] =  0;
  422.       faces[ 5][ 1] =  0;
  423.       faces[ 5][ 2] = 13;  faces[ 5][ 6] = 29;  faces[ 5][10] = 45;  faces[ 5][14] = 61;
  424.       faces[ 5][ 3] =  9;  faces[ 5][ 7] = 25;  faces[ 5][11] = 41;  faces[ 5][15] = 57;
  425.       faces[ 5][ 4] =  5;  faces[ 5][ 8] = 21;  faces[ 5][12] = 37;  faces[ 5][16] = 53;
  426.       faces[ 5][ 5] =  1;  faces[ 5][ 9] = 17;  faces[ 5][13] = 33;  faces[ 5][17] = 49;
  427.  
  428.       faces[ 6][ 0] =  0;
  429.       faces[ 6][ 1] =  0;
  430.       faces[ 6][ 2] = 14;  faces[ 6][ 6] = 30;  faces[ 6][10] = 46;  faces[ 6][14] = 62;
  431.       faces[ 6][ 3] = 10;  faces[ 6][ 7] = 26;  faces[ 6][11] = 42;  faces[ 6][15] = 58;
  432.       faces[ 6][ 4] =  6;  faces[ 6][ 8] = 22;  faces[ 6][12] = 38;  faces[ 6][16] = 54;
  433.       faces[ 6][ 5] =  2;  faces[ 6][ 9] = 18;  faces[ 6][13] = 34;  faces[ 6][17] = 50;
  434.  
  435.       faces[ 7][ 0] =  0;
  436.       faces[ 7][ 1] =  0;
  437.       faces[ 7][ 2] = 15;  faces[ 7][ 6] = 31;  faces[ 7][10] = 47;  faces[ 7][14] = 63;
  438.       faces[ 7][ 3] = 11;  faces[ 7][ 7] = 27;  faces[ 7][11] = 43;  faces[ 7][15] = 59;
  439.       faces[ 7][ 4] =  7;  faces[ 7][ 8] = 23;  faces[ 7][12] = 39;  faces[ 7][16] = 55;
  440.       faces[ 7][ 5] =  3;  faces[ 7][ 9] = 19;  faces[ 7][13] = 35;  faces[ 7][17] = 51;
  441.  
  442.       faces[ 8][ 0] =  0;
  443.       faces[ 8][ 1] =  0;
  444.       faces[ 8][ 2] = 12;  faces[ 8][ 6] = 28;  faces[ 8][10] = 44;  faces[ 8][14] = 60;
  445.       faces[ 8][ 3] = 13;  faces[ 8][ 7] = 29;  faces[ 8][11] = 45;  faces[ 8][15] = 61;
  446.       faces[ 8][ 4] = 14;  faces[ 8][ 8] = 30;  faces[ 8][12] = 46;  faces[ 8][16] = 62;
  447.       faces[ 8][ 5] = 15;  faces[ 8][ 9] = 31;  faces[ 8][13] = 47;  faces[ 8][17] = 63;
  448.  
  449.       faces[ 9][ 0] =  0;
  450.       faces[ 9][ 1] =  0;
  451.       faces[ 9][ 2] =  8;  faces[ 9][ 6] = 24;  faces[ 9][10] = 40;  faces[ 9][14] = 56;
  452.       faces[ 9][ 3] =  9;  faces[ 9][ 7] = 25;  faces[ 9][11] = 41;  faces[ 9][15] = 57;
  453.       faces[ 9][ 4] = 10;  faces[ 9][ 8] = 26;  faces[ 9][12] = 42;  faces[ 9][16] = 58;
  454.       faces[ 9][ 5] = 11;  faces[ 9][ 9] = 27;  faces[ 9][13] = 43;  faces[ 9][17] = 59;
  455.  
  456.       faces[10][ 0] =  0;
  457.       faces[10][ 1] =  0;
  458.       faces[10][ 2] =  4;  faces[10][ 6] = 20;  faces[10][10] = 36;  faces[10][14] = 52;
  459.       faces[10][ 3] =  5;  faces[10][ 7] = 21;  faces[10][11] = 37;  faces[10][15] = 53;
  460.       faces[10][ 4] =  6;  faces[10][ 8] = 22;  faces[10][12] = 38;  faces[10][16] = 54;
  461.       faces[10][ 5] =  7;  faces[10][ 9] = 23;  faces[10][13] = 39;  faces[10][17] = 55;
  462.  
  463.       faces[11][ 0] =  0;
  464.       faces[11][ 1] =  0;
  465.       faces[11][ 2] =  0;  faces[11][ 6] = 16;  faces[11][10] = 32;  faces[11][14] = 48;
  466.       faces[11][ 3] =  1;  faces[11][ 7] = 17;  faces[11][11] = 33;  faces[11][15] = 49;
  467.       faces[11][ 4] =  2;  faces[11][ 8] = 18;  faces[11][12] = 34;  faces[11][16] = 50;
  468.       faces[11][ 5] =  3;  faces[11][ 9] = 19;  faces[11][13] = 35;  faces[11][17] = 51;
  469.  
  470.       faces[12][ 0] =  0;
  471.       faces[12][ 1] =  0;
  472.       faces[12][ 2] = 12;  faces[12][ 6] = 13;  faces[12][10] = 14;  faces[12][14] = 15;
  473.       faces[12][ 3] = 24;  faces[12][ 7] = 25;  faces[12][11] = 26;  faces[12][15] = 27;
  474.       faces[12][ 4] = 36;  faces[12][ 8] = 37;  faces[12][12] = 38;  faces[12][16] = 39;
  475.       faces[12][ 5] = 48;  faces[12][ 9] = 49;  faces[12][13] = 50;  faces[12][17] = 51;
  476.  
  477.       faces[13][ 0] =  0;
  478.       faces[13][ 1] =  0;
  479.       faces[13][ 2] =  0;  faces[13][ 6] =  1;  faces[13][10] =  2;  faces[13][14] =  3;
  480.       faces[13][ 3] = 20;  faces[13][ 7] = 21;  faces[13][11] = 22;  faces[13][15] = 23;
  481.       faces[13][ 4] = 40;  faces[13][ 8] = 41;  faces[13][12] = 42;  faces[13][16] = 43;
  482.       faces[13][ 5] = 60;  faces[13][ 9] = 61;  faces[13][13] = 62;  faces[13][17] = 63;
  483.  
  484.       faces[14][ 0] =  0;
  485.       faces[14][ 1] =  0;
  486.       faces[14][ 2] = 12;  faces[14][ 6] = 28;  faces[14][10] = 44;  faces[14][14] = 60;
  487.       faces[14][ 3] =  9;  faces[14][ 7] = 25;  faces[14][11] = 41;  faces[14][15] = 57;
  488.       faces[14][ 4] =  6;  faces[14][ 8] = 22;  faces[14][12] = 38;  faces[14][16] = 54;
  489.       faces[14][ 5] =  3;  faces[14][ 9] = 19;  faces[14][13] = 35;  faces[14][17] = 51;
  490.  
  491.       faces[15][ 0] =  0;
  492.       faces[15][ 1] =  0;
  493.       faces[15][ 2] = 15;  faces[15][ 6] = 31;  faces[15][10] = 47;  faces[15][14] = 63;
  494.       faces[15][ 3] = 10;  faces[15][ 7] = 26;  faces[15][11] = 42;  faces[15][15] = 58;
  495.       faces[15][ 4] =  5;  faces[15][ 8] = 21;  faces[15][12] = 37;  faces[15][16] = 53;
  496.       faces[15][ 5] =  0;  faces[15][ 9] = 16;  faces[15][13] = 32;  faces[15][17] = 48;
  497.  
  498.       faces[16][ 0] =  0;
  499.       faces[16][ 1] =  0;
  500.       faces[16][ 2] = 12;  faces[16][ 6] = 29;  faces[16][10] = 46;  faces[16][14] = 63;
  501.       faces[16][ 3] =  8;  faces[16][ 7] = 25;  faces[16][11] = 42;  faces[16][15] = 59;
  502.       faces[16][ 4] =  4;  faces[16][ 8] = 21;  faces[16][12] = 38;  faces[16][16] = 55;
  503.       faces[16][ 5] =  0;  faces[16][ 9] = 17;  faces[16][13] = 34;  faces[16][17] = 51;
  504.  
  505.       faces[17][ 0] =  0;
  506.       faces[17][ 1] =  0;
  507.       faces[17][ 2] = 15;  faces[17][ 6] = 30;  faces[17][10] = 45;  faces[17][14] = 60;
  508.       faces[17][ 3] = 11;  faces[17][ 7] = 26;  faces[17][11] = 41;  faces[17][15] = 56;
  509.       faces[17][ 4] =  7;  faces[17][ 8] = 22;  faces[17][12] = 37;  faces[17][16] = 52;
  510.       faces[17][ 5] =  3;  faces[17][ 9] = 18;  faces[17][13] = 33;  faces[17][17] = 48;
  511.    }
  512.  
  513.    /**
  514.     *  Render the current face set in the 2D window.
  515.     */
  516.    public void render2D(Graphics gc) {
  517.  
  518.       gc.setColor(background);
  519.       gc.fillRect(0, 0, width, height);
  520.  
  521.       int id;
  522.       int x, y;
  523.  
  524.       float begX;
  525.       float begY;
  526.  
  527.       for (int l=0; l<3; l++) {
  528.          begY =  28.0f + l*(5.f*23.3f);
  529.          for (int k=0; k<6; k++) {
  530.             begX =  11.65f + k*(5.f*11.65f);
  531.             int count = 0;
  532.             int face = l*6+k;
  533.             for (int i=0; i<4; i++) {
  534.                for (int j=0; j<4; j++) {
  535.                   x = (int)begX + i*12;
  536.                   y = (int)begY + j*12;
  537.                   id = faces[face][count+2];
  538.                   if (occupied[id] == HUMAN) {
  539.                      x -= 2;
  540.                      y -= 2;
  541.                      gc.setColor(red);
  542.                      gc.fillRect(x, y, 5, 5);
  543.                   }
  544.                   else if (occupied[id] == MACHINE) {
  545.                      x -= 2;
  546.                      y -= 2;
  547.                      gc.setColor(blue);
  548.                      gc.fillRect(x, y, 5, 5);
  549.                   }
  550.                   else {
  551.                      x -= 1;
  552.                      y -= 1;
  553.                      gc.setColor(gray);
  554.                      gc.fillRect(x, y, 2, 2);
  555.                   }
  556.                   if (highlight[face]) {
  557.                      gc.setColor(yellow);
  558.                      positions.setHighlight(faces[face][count+2]);
  559.                   }
  560.                   count++;
  561.                }
  562.             }
  563.             if (highlight[face])
  564.                gc.setColor(yellow);
  565.             else
  566.                gc.setColor(white);
  567.             if ((face+1)<10)
  568.                gc.drawString("Face "+(face+1), (int)begX-2, (int)begY+60);
  569.             else
  570.                gc.drawString("Face "+(face+1), (int)begX-4, (int)begY+60);
  571.          }
  572.       }
  573.    }
  574.  
  575.    /**
  576.     *  Determine what position has been selected in the 2D window.
  577.     */
  578.    public void checkSelection2D(int x, int y, int player) {
  579.  
  580.       int id;
  581.       int posX, posY;
  582.  
  583.       float begX;
  584.       float begY;
  585.  
  586.       for (int l=0; l<3; l++) {
  587.          begY =  28.0f + l*(5.f*23.3f);
  588.          for (int k=0; k<6; k++) {
  589.             begX =  11.65f + k*(5.f*11.65f);
  590.             int count = 0;
  591.             int face = l*6+k;
  592.             for (int i=0; i<4; i++) {
  593.                for (int j=0; j<4; j++) {
  594.                   posX = (int)begX + i*12;
  595.                   posY = (int)begY + j*12;
  596.                   if (x > posX-4 && x < posX+4 &&
  597.                       y > posY-4 && y < posY+4) {
  598.  
  599.                      id = faces[face][count+2];
  600.  
  601.                      if (occupied[id] == UNOCCUPIED) {
  602.                         positions.set(id, player);
  603.                         selection(id, player);
  604.                         canvas.repaint();
  605.                      }
  606.                      return;
  607.                   }
  608.                   count++;
  609.                }
  610.             }
  611.             if ((x > begX-4  && x < begX+40) && 
  612.                 (y > begY+45 && y < begY+60)   ) {
  613.  
  614.                count = 0;
  615.                for (int i=0; i<4; i++) {
  616.                   for (int j=0; j<4; j++) {
  617.                      if (highlight[face])
  618.                         positions.clearHighlight(faces[face][count+2]);
  619.                      count++;
  620.                   }
  621.                }
  622.                if (highlight[face])
  623.                   highlight[face] = false;
  624.                else
  625.                   highlight[face] = true;
  626.                canvas.repaint();
  627.             }
  628.          }
  629.       }
  630.  
  631.    }
  632.  
  633.  
  634.    /**
  635.     *  Record the player's move.
  636.     */
  637.    public void selection(int pos, int player) {
  638.  
  639.       int num_combinations;
  640.       int comb;
  641.  
  642.       this.player = player;
  643.  
  644.       if (player == HUMAN) {
  645.  
  646.          // If position is already occupied, return.
  647.          if (occupied[pos] != 0) return;
  648.  
  649.          // Mark the position as HUMAN.
  650.          occupied[pos] = HUMAN;
  651.  
  652.          // Update the logic arrays.
  653.          this.player = update_logic_arrays(pos);
  654.  
  655.          // Have the computer determine its move.
  656.          choose_move();
  657.       }
  658.    }
  659.  
  660.  
  661.    /**
  662.     *  Determine the computer's move.
  663.     */
  664.    public void choose_move () {
  665.       
  666.       if (player == MACHINE) {
  667.  
  668.          // Babe in the woods.
  669.          if (skill_level == 0) {
  670.             if (!block_winning_move()) {
  671.                if (!pick_7()) {
  672.                   if (!check_outside_four()) {
  673.                      pick_best_position();
  674.                   }
  675.                }
  676.             }
  677.          }
  678.  
  679.          // Walk and chew gum.
  680.          else if (skill_level == 1) {
  681.             if (!block_winning_move()) {
  682.                if (!block_intersecting_rows()) {
  683.                   if (!block_inside_four()) {
  684.                      if (!block_outside_four()) {
  685.                            pick_best_position();
  686.                      }
  687.                   }
  688.                }
  689.             }
  690.          }
  691.  
  692.          // Jeopordy contestant.
  693.          else if (skill_level == 2) {
  694.             if (!block_winning_move()) {
  695.                if (!block_intersecting_rows()) {
  696.                   if (!block_inside_four()) {
  697.                      if (!block_outside_four()) {
  698.                         if (!pick_7()) {
  699.                            pick_best_position();
  700.                         }
  701.                      }
  702.                   }
  703.                }
  704.             }
  705.          }
  706.  
  707.          // Rocket scientist.
  708.          else if (skill_level == 3) {
  709.             if (!block_winning_move()) {
  710.                if (!block_intersecting_rows()) {
  711.                   if (!block_chair_move()) {
  712.                      if (!check_face_three()) {
  713.                         if (!block_central_four()) {
  714.                            if (!block_inside_four()) {
  715.                               if (!block_outside_four()) {
  716.                                  if (!take_inside_four()) {
  717.                                     if (!take_outside_four()) {
  718.                                        if (!pick_7()) {
  719.                                           if (!check_outside_four()) {
  720.                                              pick_best_position();
  721.                                           }
  722.                                        }
  723.                                     }
  724.                                  }
  725.                               }
  726.                            }
  727.                         }
  728.                      }
  729.                   }
  730.                }
  731.             }
  732.          }
  733.  
  734.          // Be afraid, be very afraid.
  735.          else if (skill_level == 4) {
  736.             if (!block_winning_move()) {
  737.                if (!block_intersecting_rows()) {
  738.                   if (!block_chair_move()) {
  739.                      if (!block_walk_move()) {
  740.                         if (!block_central_four()) {
  741.                            if (!block_inside_four()) {
  742.                               if (!block_outside_four()) {
  743.                                  if (!check_face_three()) {
  744.                                     if (!check_intersecting_rows2()) {
  745.                                        if (!take_inside_four()) {
  746.                                           if (!take_outside_four()) {
  747.                                              if (!pick_7()) {
  748.                                                 if (!check_outside_four()) {
  749.                                                    pick_best_position();
  750.                                                 }
  751.                                              }
  752.                                           }
  753.                                        }
  754.                                     }
  755.                                  }
  756.                               }
  757.                            }
  758.                         }
  759.                      }
  760.                   }
  761.                }
  762.             }
  763.          }
  764.       }
  765.    }
  766.  
  767.  
  768.    /**
  769.     *  Check for a winning move.
  770.     */
  771.    public boolean block_winning_move() {
  772.  
  773.       // Loop through each combination and see if any player occupies 
  774.       // three positions. If so, take the last remaining position.
  775.       int pos;
  776.       for (int i=0; i<76; i++) {
  777.          if (combinations[i][0] == 3) {
  778.             for (int j=2; j<6; j++) {
  779.                pos = combinations[i][j];
  780.                if (occupied[pos] == 0) {
  781.                   occupied[pos] = MACHINE;
  782.                   positions.set(pos, MACHINE);
  783.                   player = update_logic_arrays(pos);
  784.                   if (debug) System.out.println("block_winning_move:  true");
  785.                   return true;  
  786.                }
  787.             }
  788.          }
  789.       }
  790.       if (debug) System.out.println("check_winning_move:  false");
  791.       return false;
  792.    }
  793.  
  794.  
  795.    /**
  796.     *  Block outside four
  797.     */
  798.    public boolean block_outside_four() {
  799.  
  800.       int pos;
  801.       int index = 0;
  802.       int max = 0;
  803.  
  804.       // Block the opponent, if necessary.
  805.       for (int i=0; i<18; i++) {
  806.          if (outside_four[i][0] > 0 &&
  807.              outside_four[i][1] == HUMAN) {
  808.             if(outside_four[i][0] > max) {
  809.                index = i;
  810.                max = outside_four[i][0];
  811.             }
  812.          }
  813.       }
  814.  
  815.       if (max > 0) {
  816.          for (int j=2; j<6; j++) {
  817.             pos = outside_four[index][j];
  818.             if (occupied[pos] == 0) {
  819.                occupied[pos] = MACHINE;
  820.                positions.set(pos, MACHINE);
  821.                player = update_logic_arrays(pos);
  822.                if (debug) System.out.println("block_outside_four:  true");
  823.                return true;
  824.             }
  825.          }
  826.       }
  827.  
  828.       if (debug) System.out.println("block_outside_four:  false");
  829.       return false;
  830.    }
  831.  
  832.  
  833.    /**
  834.     *  Block central four
  835.     */
  836.    public boolean block_central_four() {
  837.  
  838.       int pos;   
  839.       int index = 0;
  840.       int max = 0;
  841.  
  842.       // Block the opponent, if necessary.
  843.       for (int i=1; i<3; i++) {
  844.          if (inside_four[i][0] > 0 &&
  845.              inside_four[i][1] == HUMAN) {
  846.             if(inside_four[i][0] > max) {
  847.                index = i;
  848.                max = inside_four[i][0];
  849.             }
  850.          }
  851.       }   
  852.  
  853.       if (max > 0) {
  854.          for (int j=2; j<6; j++) {
  855.             pos = inside_four[index][j];
  856.             if (occupied[pos] == 0) {
  857.                occupied[pos] = MACHINE;
  858.                positions.set(pos, MACHINE);
  859.                player = update_logic_arrays(pos);
  860.                if (debug) System.out.println("block_central_four:  true");
  861.                return true;
  862.             }
  863.          }
  864.       }   
  865.  
  866.       if (debug) System.out.println("block_central_four:  false");
  867.       return false;
  868.    }
  869.  
  870.    /**   
  871.     *  Check each face for a forced win.
  872.     */   
  873.    public boolean check_face_three() {
  874.      
  875.       int pos;   
  876.       int index = 0;
  877.       int human = 0;
  878.       int machine = 0;
  879.  
  880.       // Block the opponent from a forced win.
  881.       for (int i=0; i<18; i++) {
  882.          if (outside_four[i][0] == -1) {
  883.             human = 0;
  884.             machine = 0;
  885.             for (int j=2; j<6; j++) {
  886.                if (occupied[outside_four[i][j]] == MACHINE)
  887.                   machine++;
  888.                else if (occupied[outside_four[i][j]] == HUMAN)
  889.                   human++;
  890.             }
  891.             if (debug) System.out.println("machine = " + machine);
  892.             if (debug) System.out.println("human   = " + human);
  893.             if (human == 3 && machine == 1) {
  894.                if (debug) System.out.println("human == 3 && machine == 1");
  895.                for (int j=2; j<18; j++) {
  896.                   pos  = faces[i][j];
  897.                   if (occupied[pos] == 0) { 
  898.                      for (int k=0; k<76; k++) {
  899.                         if (combinations[i][0] == 2 &
  900.                             combinations[i][1] == HUMAN) {
  901.                            for (int l=0; l<4; l++) {
  902.                               if (combinations[i][l] == pos) {
  903.                                  occupied[pos] = MACHINE;
  904.                                  positions.set(pos, MACHINE);
  905.                                  player = update_logic_arrays(pos);
  906.                                  if (debug) System.out.println("check_face_three:  true");
  907.                                  return true;
  908.                               }
  909.                            }
  910.                         }
  911.                      }
  912.                   }
  913.                }
  914.             }
  915.          }
  916.       }     
  917.          
  918.       if (debug) System.out.println("check_face_three:  false");
  919.       return false;
  920.    }
  921.  
  922.  
  923.  
  924.    /**
  925.     *  Block inside four
  926.     */
  927.    public boolean block_inside_four() {
  928.  
  929.       int pos;
  930.       int index = 0;
  931.       int max = 0;
  932.  
  933.       // Block the opponent, if necessary.
  934.       for (int i=0; i<18; i++) {
  935.          if (inside_four[i][0] > 0 &&
  936.              inside_four[i][1] == HUMAN) {
  937.             if(inside_four[i][0] > max) {
  938.                index = i;
  939.                max = inside_four[i][0];
  940.             }
  941.          }
  942.       }   
  943.  
  944.       if (max > 0) {
  945.          for (int j=2; j<6; j++) {
  946.             pos = inside_four[index][j];
  947.             if (occupied[pos] == 0) {
  948.                occupied[pos] = MACHINE;
  949.                positions.set(pos, MACHINE);
  950.                player = update_logic_arrays(pos);
  951.                if (debug) System.out.println("block_inside_four:  true");
  952.                return true;
  953.             }
  954.          }
  955.       }   
  956.  
  957.       if (debug) System.out.println("block_inside_four:  false");
  958.       return false;
  959.    }
  960.  
  961.  
  962.    public boolean block_chair_move() {
  963.  
  964.       int pos;
  965.  
  966.       int ncorners = 0;    // Number of corners owned by human
  967.       int corner   = 0;    // Corner owned by machine
  968.  
  969.       if (debug) System.out.println("inside block_chair_move");
  970.  
  971.       // Loop through all of the faces.
  972.       for(int i=0; i<18; i++) {
  973.  
  974.          // Determine which corners the human owns.
  975.          if (occupied[faces[i][2]] == HUMAN)
  976.             ncorners++;   
  977.          else if (occupied[faces[i][2]] == MACHINE)
  978.             corner = 2;
  979.          if (occupied[faces[i][5]] == HUMAN) 
  980.             ncorners++;   
  981.          else if (occupied[faces[i][5]] == MACHINE)
  982.             corner = 5;
  983.          if (occupied[faces[i][14]] == HUMAN)
  984.             ncorners++;   
  985.          else if (occupied[faces[i][14]] == MACHINE)
  986.             corner = 14;
  987.          if (occupied[faces[i][17]] == HUMAN)
  988.             ncorners++;   
  989.          else if (occupied[faces[i][17]] == MACHINE)
  990.             corner = 17;
  991.  
  992.          // If the human owns three corners, continue with the search.
  993.          if (ncorners == 3) {
  994.             if (corner == 2) {
  995.                if (occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][ 7]] == 0 &&
  996.                    occupied[faces[i][ 8]] == 0     && occupied[faces[i][11]] == 0 &&
  997.                    occupied[faces[i][15]] == 0     && occupied[faces[i][16]] == 0) {
  998.                   pos = faces[i][11];
  999.                   occupied[pos] = MACHINE;
  1000.                   positions.set(pos, MACHINE);
  1001.                   player = update_logic_arrays(pos);
  1002.                   if (debug) System.out.println("block_chair_move: found");
  1003.                   return true;
  1004.                }
  1005.                if (occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][ 8]] == 0 &&
  1006.                    occupied[faces[i][11]] == 0     && occupied[faces[i][12]] == 0 &&
  1007.                    occupied[faces[i][15]] == 0     && occupied[faces[i][16]] == 0) {
  1008.                   pos = faces[i][12];
  1009.                   occupied[pos] = MACHINE;
  1010.                   positions.set(pos, MACHINE);
  1011.                   player = update_logic_arrays(pos);
  1012.                   if (debug) System.out.println("block_chair_move: found");
  1013.                   return true;
  1014.                }
  1015.                if (occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 7]] == 0 &&
  1016.                    occupied[faces[i][ 8]] == 0     && occupied[faces[i][ 9]] == 0 &&
  1017.                    occupied[faces[i][11]] == 0     && occupied[faces[i][13]] == 0) {
  1018.                   pos = faces[i][8];
  1019.                   occupied[pos] = MACHINE;
  1020.                   positions.set(pos, MACHINE);
  1021.                   player = update_logic_arrays(pos);
  1022.                   if (debug) System.out.println("block_chair_move: found");
  1023.                   return true;
  1024.                }
  1025.                if (occupied[faces[i][10]] == HUMAN && occupied[faces[i][ 8]] == 0 &&
  1026.                    occupied[faces[i][ 9]] == 0     && occupied[faces[i][11]] == 0 &&
  1027.                    occupied[faces[i][12]] == 0     && occupied[faces[i][13]] == 0) {
  1028.                   pos = faces[i][11];
  1029.                   occupied[pos] = MACHINE;
  1030.                   positions.set(pos, MACHINE);
  1031.                   player = update_logic_arrays(pos);
  1032.                   if (debug) System.out.println("block_chair_move: found");
  1033.                   return true;
  1034.                }
  1035.                if (occupied[faces[i][ 7]] == HUMAN && occupied[faces[i][ 3]] == 0 &&
  1036.                    occupied[faces[i][ 8]] == 0     && occupied[faces[i][11]] == 0 &&
  1037.                    occupied[faces[i][15]] == 0     && occupied[faces[i][16]] == 0) {
  1038.                   pos = faces[i][11];
  1039.                   occupied[pos] = MACHINE;
  1040.                   positions.set(pos, MACHINE);
  1041.                   player = update_logic_arrays(pos);
  1042.                   if (debug) System.out.println("block_chair_move: found");
  1043.                   return true;
  1044.                }
  1045.                if (occupied[faces[i][12]] == HUMAN && occupied[faces[i][ 4]] == 0 &&
  1046.                    occupied[faces[i][ 8]] == 0     && occupied[faces[i][11]] == 0 &&
  1047.                    occupied[faces[i][15]] == 0     && occupied[faces[i][16]] == 0) {
  1048.                   pos = faces[i][16];
  1049.                   occupied[pos] = MACHINE;
  1050.                   positions.set(pos, MACHINE);
  1051.                   player = update_logic_arrays(pos);
  1052.                   if (debug) System.out.println("block_chair_move: found");
  1053.                   return true;
  1054.                }
  1055.             }
  1056.             else if (corner == 5) {
  1057.                if (occupied[faces[i][ 9]] == HUMAN && occupied[faces[i][ 6]] == 0 &&
  1058.                    occupied[faces[i][ 7]] == 0     && occupied[faces[i][ 8]] == 0 &&
  1059.                    occupied[faces[i][10]] == 0     && occupied[faces[i][12]] == 0) {
  1060.                   pos = faces[i][7];
  1061.                   occupied[pos] = MACHINE;
  1062.                   positions.set(pos, MACHINE);
  1063.                   player = update_logic_arrays(pos);
  1064.                   if (debug) System.out.println("block_chair_move: found");
  1065.                   return true;
  1066.                }
  1067.                if (occupied[faces[i][13]] == HUMAN && occupied[faces[i][ 7]] == 0 &&
  1068.                    occupied[faces[i][ 7]] == 0     && occupied[faces[i][10]] == 0 &&
  1069.                    occupied[faces[i][11]] == 0     && occupied[faces[i][12]] == 0) {
  1070.                   pos = faces[i][12];
  1071.                   occupied[pos] = MACHINE;
  1072.                   positions.set(pos, MACHINE);
  1073.                   player = update_logic_arrays(pos);
  1074.                   if (debug) System.out.println("block_chair_move: found");
  1075.                   return true;
  1076.                }
  1077.                if (occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][ 8]] == 0 &&
  1078.                    occupied[faces[i][11]] == 0     && occupied[faces[i][12]] == 0 &&
  1079.                    occupied[faces[i][15]] == 0     && occupied[faces[i][16]] == 0) {
  1080.                   pos = faces[i][12];
  1081.                   occupied[pos] = MACHINE;
  1082.                   positions.set(pos, MACHINE);
  1083.                   player = update_logic_arrays(pos);
  1084.                   if (debug) System.out.println("block_chair_move: found");
  1085.                   return true;
  1086.                }
  1087.                if (occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][ 7]] == 0 &&
  1088.                    occupied[faces[i][11]] == 0     && occupied[faces[i][12]] == 0 &&
  1089.                    occupied[faces[i][15]] == 0     && occupied[faces[i][16]] == 0) {
  1090.                   pos = faces[i][7];
  1091.                   occupied[pos] = MACHINE;
  1092.                   positions.set(pos, MACHINE);
  1093.                   player = update_logic_arrays(pos);
  1094.                   if (debug) System.out.println("block_chair_move: found");
  1095.                   return true;
  1096.                }
  1097.                if (occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][ 4]] == 0 &&
  1098.                    occupied[faces[i][11]] == 0     && occupied[faces[i][12]] == 0 &&
  1099.                    occupied[faces[i][15]] == 0     && occupied[faces[i][16]] == 0) {
  1100.                   pos = faces[i][12];
  1101.                   occupied[pos] = MACHINE;
  1102.                   positions.set(pos, MACHINE);
  1103.                   player = update_logic_arrays(pos);
  1104.                   if (debug) System.out.println("block_chair_move: found");
  1105.                   return true;
  1106.                }
  1107.                if (occupied[faces[i][11]] == HUMAN && occupied[faces[i][ 3]] == 0 &&
  1108.                    occupied[faces[i][ 7]] == 0     && occupied[faces[i][12]] == 0 &&
  1109.                    occupied[faces[i][15]] == 0     && occupied[faces[i][16]] == 0) {
  1110.                   pos = faces[i][ 7];
  1111.                   occupied[pos] = MACHINE;
  1112.                   positions.set(pos, MACHINE);
  1113.                   player = update_logic_arrays(pos);
  1114.                   if (debug) System.out.println("block_chair_move: found");
  1115.                   return true;
  1116.                }
  1117.             }
  1118.             else if (corner == 14) {
  1119.                if (occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 7]] == 0 &&
  1120.                    occupied[faces[i][ 8]] == 0     && occupied[faces[i][ 9]] == 0 &&
  1121.                    occupied[faces[i][11]] == 0     && occupied[faces[i][13]] == 0) {
  1122.                   pos = faces[i][7];
  1123.                   occupied[pos] = MACHINE;
  1124.                   positions.set(pos, MACHINE);
  1125.                   player = update_logic_arrays(pos);
  1126.                   if (debug) System.out.println("block_chair_move: found");
  1127.                   return true;
  1128.                }
  1129.                if (occupied[faces[i][10]] == HUMAN && occupied[faces[i][ 8]] == 0 &&
  1130.                    occupied[faces[i][ 9]] == 0     && occupied[faces[i][11]] == 0 &&
  1131.                    occupied[faces[i][12]] == 0     && occupied[faces[i][13]] == 0) {
  1132.                   pos = faces[i][12];
  1133.                   occupied[pos] = MACHINE;
  1134.                   positions.set(pos, MACHINE);
  1135.                   player = update_logic_arrays(pos);
  1136.                   if (debug) System.out.println("block_chair_move: found");
  1137.                   return true;
  1138.                }
  1139.                if (occupied[faces[i][15]] == HUMAN && occupied[faces[i][ 3]] == 0 &&
  1140.                    occupied[faces[i][ 4]] == 0     && occupied[faces[i][ 7]] == 0 &&
  1141.                    occupied[faces[i][11]] == 0     && occupied[faces[i][12]] == 0) {
  1142.                   pos = faces[i][3];
  1143.                   occupied[pos] = MACHINE;
  1144.                   positions.set(pos, MACHINE);
  1145.                   player = update_logic_arrays(pos);
  1146.                   if (debug) System.out.println("block_chair_move: found");
  1147.                   return true;
  1148.                }
  1149.                if (occupied[faces[i][16]] == HUMAN && occupied[faces[i][ 3]] == 0 &&
  1150.                    occupied[faces[i][ 4]] == 0     && occupied[faces[i][ 7]] == 0 &&
  1151.                    occupied[faces[i][ 8]] == 0     && occupied[faces[i][12]] == 0) {
  1152.                   pos = faces[i][12];
  1153.                   occupied[pos] = MACHINE;
  1154.                   positions.set(pos, MACHINE);
  1155.                   player = update_logic_arrays(pos);
  1156.                   if (debug) System.out.println("block_chair_move: found");
  1157.                   return true;
  1158.                }
  1159.                if (occupied[faces[i][11]] == HUMAN && occupied[faces[i][ 3]] == 0 &&
  1160.                    occupied[faces[i][ 4]] == 0     && occupied[faces[i][ 7]] == 0 &&
  1161.                    occupied[faces[i][12]] == 0     && occupied[faces[i][15]] == 0) {
  1162.                   pos = faces[i][7];
  1163.                   occupied[pos] = MACHINE;
  1164.                   positions.set(pos, MACHINE);
  1165.                   player = update_logic_arrays(pos);
  1166.                   if (debug) System.out.println("block_chair_move: found");
  1167.                   return true;
  1168.                }
  1169.                if (occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][ 6]] == 0 &&
  1170.                    occupied[faces[i][ 7]] == 0     && occupied[faces[i][ 9]] == 0 &&
  1171.                    occupied[faces[i][12]] == 0     && occupied[faces[i][13]] == 0) {
  1172.                   pos = faces[i][7];
  1173.                   occupied[pos] = MACHINE;
  1174.                   positions.set(pos, MACHINE);
  1175.                   player = update_logic_arrays(pos);
  1176.                   if (debug) System.out.println("block_chair_move: found");
  1177.                   return true;
  1178.                }
  1179.             }
  1180.             else if (corner == 17) {
  1181.                if (occupied[faces[i][ 9]] == HUMAN && occupied[faces[i][ 6]] == 0 &&
  1182.                    occupied[faces[i][ 7]] == 0     && occupied[faces[i][ 8]] == 0 &&
  1183.                    occupied[faces[i][10]] == 0     && occupied[faces[i][11]] == 0) {
  1184.                   pos = faces[i][8];
  1185.                   occupied[pos] = MACHINE;
  1186.                   positions.set(pos, MACHINE);
  1187.                   player = update_logic_arrays(pos);
  1188.                   if (debug) System.out.println("block_chair_move: found");
  1189.                   return true;
  1190.                }
  1191.                if (occupied[faces[i][13]] == HUMAN && occupied[faces[i][ 6]] == 0 &&
  1192.                    occupied[faces[i][ 8]] == 0     && occupied[faces[i][10]] == 0 &&
  1193.                    occupied[faces[i][11]] == 0     && occupied[faces[i][12]] == 0) {
  1194.                   pos = faces[i][11];
  1195.                   occupied[pos] = MACHINE;
  1196.                   positions.set(pos, MACHINE);
  1197.                   player = update_logic_arrays(pos);
  1198.                   if (debug) System.out.println("block_chair_move: found");
  1199.                   return true;
  1200.                }
  1201.                if (occupied[faces[i][15]] == HUMAN && occupied[faces[i][ 3]] == 0 &&
  1202.                    occupied[faces[i][ 4]] == 0     && occupied[faces[i][ 7]] == 0 &&
  1203.                    occupied[faces[i][ 8]] == 0     && occupied[faces[i][11]] == 0) {
  1204.                   pos = faces[i][11];
  1205.                   occupied[pos] = MACHINE;
  1206.                   positions.set(pos, MACHINE);
  1207.                   player = update_logic_arrays(pos);
  1208.                   if (debug) System.out.println("block_chair_move: found");
  1209.                   return true;
  1210.                }
  1211.                if (occupied[faces[i][16]] == HUMAN && occupied[faces[i][ 3]] == 0 &&
  1212.                    occupied[faces[i][ 4]] == 0     && occupied[faces[i][ 8]] == 0 &&
  1213.                    occupied[faces[i][11]] == 0     && occupied[faces[i][12]] == 0) {
  1214.                   pos = faces[i][8];
  1215.                   occupied[pos] = MACHINE;
  1216.                   positions.set(pos, MACHINE);
  1217.                   player = update_logic_arrays(pos);
  1218.                   if (debug) System.out.println("block_chair_move: found");
  1219.                   return true;
  1220.                }
  1221.                if (occupied[faces[i][12]] == HUMAN && occupied[faces[i][ 3]] == 0 &&
  1222.                    occupied[faces[i][ 4]] == 0     && occupied[faces[i][ 8]] == 0 &&
  1223.                    occupied[faces[i][11]] == 0     && occupied[faces[i][16]] == 0) {
  1224.                   pos = faces[i][8];
  1225.                   occupied[pos] = MACHINE;
  1226.                   positions.set(pos, MACHINE);
  1227.                   player = update_logic_arrays(pos);
  1228.                   if (debug) System.out.println("block_chair_move: found");
  1229.                   return true;
  1230.                }
  1231.                if (occupied[faces[i][ 7]] == HUMAN && occupied[faces[i][ 3]] == 0 &&
  1232.                    occupied[faces[i][ 4]] == 0     && occupied[faces[i][ 8]] == 0 &&
  1233.                    occupied[faces[i][11]] == 0     && occupied[faces[i][15]] == 0) {
  1234.                   pos = faces[i][11];
  1235.                   occupied[pos] = MACHINE;
  1236.                   positions.set(pos, MACHINE);
  1237.                   player = update_logic_arrays(pos);
  1238.                   if (debug) System.out.println("block_chair_move: found");
  1239.                   return true;
  1240.                }
  1241.             }
  1242.          }
  1243.          ncorners = 0;
  1244.          corner   = -1;
  1245.       }
  1246.       if (debug) System.out.println("block_chair_move: false");
  1247.       return false;
  1248.    }
  1249.  
  1250.    public boolean block_walk_move() {
  1251.  
  1252.       int pos;
  1253.  
  1254.       if (debug) System.out.println("inside block_walk_move");
  1255.  
  1256.       // Loop through all of the faces.
  1257.       for(int i=0; i<18; i++) {
  1258.  
  1259.          // Look for a matching pattern.
  1260.          if (occupied[faces[i][ 2]] == HUMAN && occupied[faces[i][14]] == HUMAN &&
  1261.              occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][15]] == HUMAN &&
  1262.              occupied[faces[i][ 6]] == 0     && occupied[faces[i][10]] == 0     &&
  1263.              occupied[faces[i][ 7]] == 0     && occupied[faces[i][11]] == 0) {
  1264.  
  1265.             if (occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][ 9]] == 0) {
  1266.                pos = faces[i][6];
  1267.                occupied[pos] = MACHINE;
  1268.                positions.set(pos, MACHINE);
  1269.                player = update_logic_arrays(pos);
  1270.                return true;
  1271.             }
  1272.             else if (occupied[faces[i][12]] == HUMAN && occupied[faces[i][13]] == 0) {
  1273.                pos = faces[i][10];
  1274.                occupied[pos] = MACHINE;
  1275.                positions.set(pos, MACHINE);
  1276.                player = update_logic_arrays(pos);
  1277.                return true;
  1278.             }
  1279.          }
  1280.  
  1281.          // Look for a matching pattern.
  1282.          if (occupied[faces[i][14]] == HUMAN && occupied[faces[i][17]] == HUMAN &&
  1283.              occupied[faces[i][10]] == HUMAN && occupied[faces[i][13]] == HUMAN &&
  1284.              occupied[faces[i][15]] == 0     && occupied[faces[i][16]] == 0     &&
  1285.              occupied[faces[i][11]] == 0     && occupied[faces[i][12]] == 0) {
  1286.  
  1287.             if (occupied[faces[i][7]] == HUMAN && occupied[faces[i][3]] == 0) {
  1288.                pos = faces[i][15];
  1289.                occupied[pos] = MACHINE;
  1290.                positions.set(pos, MACHINE);
  1291.                player = update_logic_arrays(pos);
  1292.                return true;
  1293.             }
  1294.             else if (occupied[faces[i][8]] == HUMAN && occupied[faces[i][4]] == 0) {
  1295.                pos = faces[i][16];
  1296.                occupied[pos] = MACHINE;
  1297.                positions.set(pos, MACHINE);
  1298.                player = update_logic_arrays(pos);
  1299.                return true;
  1300.             }
  1301.          }
  1302.  
  1303.          // Look for a matching pattern.
  1304.          if (occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][16]] == HUMAN &&
  1305.              occupied[faces[i][ 5]] == HUMAN && occupied[faces[i][17]] == HUMAN &&
  1306.              occupied[faces[i][ 8]] == 0     && occupied[faces[i][12]] == 0     &&
  1307.              occupied[faces[i][ 9]] == 0     && occupied[faces[i][13]] == 0) {
  1308.  
  1309.             if (occupied[faces[i][11]] == HUMAN && occupied[faces[i][10]] == 0) {
  1310.                pos = faces[i][18];
  1311.                occupied[pos] = MACHINE;
  1312.                positions.set(pos, MACHINE);
  1313.                player = update_logic_arrays(pos);
  1314.                return true;
  1315.             }
  1316.             else if (occupied[faces[i][7]] == HUMAN && occupied[faces[i][6]] == 0) {
  1317.                pos = faces[i][9];
  1318.                occupied[pos] = MACHINE;
  1319.                positions.set(pos, MACHINE);
  1320.                player = update_logic_arrays(pos);
  1321.                return true;
  1322.             }
  1323.          }
  1324.  
  1325.          // Look for a matching pattern.
  1326.          if (occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 9]] == HUMAN &&
  1327.              occupied[faces[i][ 2]] == HUMAN && occupied[faces[i][ 5]] == HUMAN &&
  1328.              occupied[faces[i][ 7]] == 0     && occupied[faces[i][ 8]] == 0     &&
  1329.              occupied[faces[i][ 3]] == 0     && occupied[faces[i][ 4]] == 0) {
  1330.  
  1331.             if (occupied[faces[i][11]] == HUMAN && occupied[faces[i][15]] == 0) {
  1332.                pos = faces[i][3];
  1333.                occupied[pos] = MACHINE;
  1334.                positions.set(pos, MACHINE);
  1335.                player = update_logic_arrays(pos);
  1336.                return true;
  1337.             }
  1338.             else if (occupied[faces[i][12]] == HUMAN && occupied[faces[i][16]] == 0) {
  1339.                pos = faces[i][4];
  1340.                occupied[pos] = MACHINE;
  1341.                positions.set(pos, MACHINE);
  1342.                player = update_logic_arrays(pos);
  1343.                return true;
  1344.             }
  1345.          }
  1346.  
  1347.          // Look for a matching pattern.
  1348.          if (occupied[faces[i][ 2]] == HUMAN && occupied[faces[i][14]] == HUMAN &&
  1349.              occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][16]] == HUMAN &&
  1350.              occupied[faces[i][ 6]] == 0     && occupied[faces[i][10]] == 0     &&
  1351.              occupied[faces[i][ 8]] == 0     && occupied[faces[i][12]] == 0) {
  1352.  
  1353.             if ((occupied[faces[i][7]] == HUMAN && occupied[faces[i][9]] == 0) ||
  1354.                 (occupied[faces[i][9]] == HUMAN && occupied[faces[i][7]] == 0)   ) {
  1355.                pos = faces[i][6];
  1356.                occupied[pos] = MACHINE;
  1357.                positions.set(pos, MACHINE);
  1358.                player = update_logic_arrays(pos);
  1359.                return true;
  1360.             }
  1361.             else if ((occupied[faces[i][11]] == HUMAN && occupied[faces[i][13]] == 0) ||
  1362.                      (occupied[faces[i][13]] == HUMAN && occupied[faces[i][11]] == 0)   ) {
  1363.                pos = faces[i][10];
  1364.                occupied[pos] = MACHINE;
  1365.                positions.set(pos, MACHINE);
  1366.                player = update_logic_arrays(pos);
  1367.                return true;
  1368.             }
  1369.          }
  1370.  
  1371.          // Look for a matching pattern.
  1372.          if (occupied[faces[i][14]] == HUMAN && occupied[faces[i][17]] == HUMAN &&
  1373.              occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 9]] == HUMAN &&
  1374.              occupied[faces[i][15]] == 0     && occupied[faces[i][16]] == 0     &&
  1375.              occupied[faces[i][ 7]] == 0     && occupied[faces[i][ 8]] == 0) {
  1376.  
  1377.             if ((occupied[faces[i][11]] == HUMAN && occupied[faces[i][ 3]] == 0) ||
  1378.                 (occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][11]] == 0)   ) {
  1379.                pos = faces[i][15];
  1380.                occupied[pos] = MACHINE;
  1381.                positions.set(pos, MACHINE);
  1382.                player = update_logic_arrays(pos);
  1383.                return true;
  1384.             }
  1385.             else if ((occupied[faces[i][12]] == HUMAN && occupied[faces[i][ 4]] == 0) ||
  1386.                      (occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][12]] == 0)   ) {
  1387.                pos = faces[i][16];
  1388.                occupied[pos] = MACHINE;
  1389.                positions.set(pos, MACHINE);
  1390.                player = update_logic_arrays(pos);
  1391.                return true;
  1392.             }
  1393.          }
  1394.  
  1395.          // Look for a matching pattern.
  1396.          if (occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][15]] == HUMAN &&
  1397.              occupied[faces[i][ 5]] == HUMAN && occupied[faces[i][17]] == HUMAN &&
  1398.              occupied[faces[i][ 7]] == 0     && occupied[faces[i][11]] == 0     &&
  1399.              occupied[faces[i][ 9]] == 0     && occupied[faces[i][13]] == 0) {
  1400.  
  1401.             if ((occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 8]] == 0) ||
  1402.                 (occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][ 6]] == 0)   ) {
  1403.                pos = faces[i][9];
  1404.                occupied[pos] = MACHINE;
  1405.                positions.set(pos, MACHINE);
  1406.                player = update_logic_arrays(pos);
  1407.                return true;
  1408.             }
  1409.             else if ((occupied[faces[i][10]] == HUMAN && occupied[faces[i][12]] == 0) ||
  1410.                      (occupied[faces[i][12]] == HUMAN && occupied[faces[i][10]] == 0)   ) {
  1411.                pos = faces[i][13];
  1412.                occupied[pos] = MACHINE;
  1413.                positions.set(pos, MACHINE);
  1414.                player = update_logic_arrays(pos);
  1415.                return true;
  1416.             }
  1417.          }
  1418.  
  1419.          // Look for a matching pattern.
  1420.          if (occupied[faces[i][10]] == HUMAN && occupied[faces[i][13]] == HUMAN &&
  1421.              occupied[faces[i][ 2]] == HUMAN && occupied[faces[i][ 5]] == HUMAN &&
  1422.              occupied[faces[i][11]] == 0     && occupied[faces[i][12]] == 0     &&
  1423.              occupied[faces[i][ 3]] == 0     && occupied[faces[i][ 4]] == 0) {
  1424.  
  1425.             if ((occupied[faces[i][ 7]] == HUMAN && occupied[faces[i][15]] == 0) ||
  1426.                 (occupied[faces[i][15]] == HUMAN && occupied[faces[i][ 7]] == 0)   ) {
  1427.                pos = faces[i][3];
  1428.                occupied[pos] = MACHINE;
  1429.                positions.set(pos, MACHINE);
  1430.                player = update_logic_arrays(pos);
  1431.                return true;
  1432.             }
  1433.             else if ((occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][16]] == 0) ||
  1434.                      (occupied[faces[i][16]] == HUMAN && occupied[faces[i][ 8]] == 0)   ) {
  1435.                pos = faces[i][4];
  1436.                occupied[pos] = MACHINE;
  1437.                positions.set(pos, MACHINE);
  1438.                player = update_logic_arrays(pos);
  1439.                return true;
  1440.             }
  1441.          }
  1442.  
  1443.       }
  1444.  
  1445.       if (debug) System.out.println("block_walk_move: false");
  1446.       return false;
  1447.    }
  1448.  
  1449.    public boolean check_chair_move() {
  1450.  
  1451.       int pos;
  1452.  
  1453.       // If the "block chair flag" is set, all we need to do is
  1454.       // block the winning path...
  1455.       if (block_chair_flag) {
  1456.          pos = faces[block_chair_face][block_chair_next_move];
  1457.          occupied[pos] = MACHINE;
  1458.          positions.set(pos, MACHINE);
  1459.          player = update_logic_arrays(pos);
  1460.          if (debug) System.out.println("block_chair_move: march");
  1461.          return true;
  1462.       }
  1463.  
  1464.       int ncorners = 0;    // Number of corners owned by human
  1465.       int corner   = 0;    // Corner owned by machine
  1466.  
  1467.       // Loop through all of the faces.
  1468.       for(int i=0; i<18; i++) {
  1469.  
  1470.          // Determine which corners the human owns.
  1471.          if (faces[i][ 2] == HUMAN)
  1472.             ncorners++;   
  1473.          else
  1474.             corner = 2;
  1475.          if (faces[i][ 5] == HUMAN) 
  1476.             ncorners++;   
  1477.          else
  1478.             corner = 5;
  1479.          if (faces[i][14] == HUMAN)
  1480.             ncorners++;   
  1481.          else
  1482.             corner = 14;
  1483.          if (faces[i][17] == HUMAN)
  1484.             ncorners++;   
  1485.          else
  1486.             corner = 17;
  1487.  
  1488.          // If the human owns three corners, continue with the search.
  1489.          if (ncorners == 3) {
  1490.             if (corner == 2) {
  1491.                if (faces[i][ 3] == HUMAN && faces[i][ 7] == 0 &&
  1492.                    faces[i][ 8] == 0     && faces[i][11] == 0 &&
  1493.                    faces[i][15] == 0     && faces[i][16] == 0) {
  1494.                   block_chair_flag = true;
  1495.                   block_chair_next_move = 11;
  1496.                   block_chair_face = i;
  1497.                   pos = faces[i][15];
  1498.                   occupied[pos] = MACHINE;
  1499.                   positions.set(pos, MACHINE);
  1500.                   player = update_logic_arrays(pos);
  1501.                   if (debug) System.out.println("block_chair_move: found");
  1502.                   return true;
  1503.                }
  1504.                if (faces[i][ 4] == HUMAN && faces[i][ 8] == 0 &&
  1505.                    faces[i][11] == 0     && faces[i][12] == 0 &&
  1506.                    faces[i][15] == 0     && faces[i][16] == 0) {
  1507.                   block_chair_flag = true;
  1508.                   block_chair_next_move = 16;
  1509.                   block_chair_face = i;
  1510.                   pos = faces[i][8];
  1511.                   occupied[pos] = MACHINE;
  1512.                   positions.set(pos, MACHINE);
  1513.                   player = update_logic_arrays(pos);
  1514.                   if (debug) System.out.println("block_chair_move: found");
  1515.                   return true;
  1516.                }
  1517.             }
  1518.             else if (corner == 5) {
  1519.                   block_chair_flag = true;
  1520.                   block_chair_next_move = 11;
  1521.                   block_chair_face = i;
  1522.                   pos = faces[i][15];
  1523.                   occupied[pos] = MACHINE;
  1524.                   positions.set(pos, MACHINE);
  1525.                   player = update_logic_arrays(pos);
  1526.                   if (debug) System.out.println("check_face_three:  true");
  1527.                   return true;
  1528.             }
  1529.             else if (corner == 14) {
  1530.                   block_chair_flag = true;
  1531.                   block_chair_next_move = 11;
  1532.                   block_chair_face = i;
  1533.                   pos = faces[i][15];
  1534.                   occupied[pos] = MACHINE;
  1535.                   positions.set(pos, MACHINE);
  1536.                   player = update_logic_arrays(pos);
  1537.                   if (debug) System.out.println("check_face_three:  true");
  1538.                   return true;
  1539.             }
  1540.             else if (corner == 17) {
  1541.                   block_chair_flag = true;
  1542.                   block_chair_next_move = 11;
  1543.                   block_chair_face = i;
  1544.                   pos = faces[i][15];
  1545.                   occupied[pos] = MACHINE;
  1546.                   positions.set(pos, MACHINE);
  1547.                   player = update_logic_arrays(pos);
  1548.                   if (debug) System.out.println("check_face_three:  true");
  1549.                   return true;
  1550.             }
  1551.          }
  1552.       }
  1553.       return false;
  1554.    }
  1555.  
  1556.    /**
  1557.     *  Take inside four
  1558.     */
  1559.    public boolean take_inside_four() {
  1560.  
  1561.       int pos = 0;
  1562.       boolean found = false;
  1563.  
  1564.       if (occupied[21] == 0) {
  1565.          found = true;
  1566.          pos = 21;
  1567.       }
  1568.       else if (occupied[22] == 0) {
  1569.          found = true;
  1570.          pos = 22;
  1571.       }
  1572.       else if (occupied[25] == 0) {
  1573.          found = true;
  1574.          pos = 25;
  1575.       }
  1576.       else if (occupied[26] == 0) {
  1577.          found = true;
  1578.          pos = 26;
  1579.       }
  1580.       else if (occupied[37] == 0) {
  1581.          found = true;
  1582.          pos = 37;
  1583.       }
  1584.       else if (occupied[38] == 0) {
  1585.          found = true;
  1586.          pos = 38;
  1587.       }
  1588.       else if (occupied[41] == 0) {
  1589.          found = true;
  1590.          pos = 41;
  1591.       }
  1592.       else if (occupied[42] == 0) {
  1593.          found = true;
  1594.          pos = 42;
  1595.       }
  1596.  
  1597.       if (found) {
  1598.          occupied[pos] = MACHINE;
  1599.          positions.set(pos, MACHINE);
  1600.          player = update_logic_arrays(pos);
  1601.          if (debug) System.out.println("take_inside_four:  true");
  1602.          return true;
  1603.       }
  1604.  
  1605.       if (debug) System.out.println("take_inside_four:  false");
  1606.       return false;
  1607.    }
  1608.  
  1609.  
  1610.    /**
  1611.     *  Check occupancy of outside four.
  1612.     */
  1613.    public boolean check_outside_four() {
  1614.  
  1615.       int pos = 0;
  1616.  
  1617.       // Finish off the four corner combination.
  1618.       if (outside_four_flag) {
  1619.          if (occupied[faces[face_index][7]] == 0) {
  1620.             pos = faces[face_index][7];
  1621.          }
  1622.          else if (occupied[faces[face_index][6]] == 0) {
  1623.             pos = faces[face_index][6];
  1624.          }
  1625.        
  1626.          if (occupied[pos] == 0) {
  1627.             occupied[pos] = MACHINE;
  1628.             positions.set(pos, MACHINE);
  1629.             player = update_logic_arrays(pos);
  1630.             return true;  
  1631.          }
  1632.       }
  1633.  
  1634.       // Look for a four corner combination.
  1635.       for (int i=0; i<18; i++) {
  1636.          if (outside_four[i][0] == 4 &&
  1637.              outside_four[i][1] == MACHINE) {
  1638.             if (faces[i][0] > 0 &&
  1639.                 faces[i][1] == MACHINE) {
  1640.                if (occupied[faces[i][8]] == 0) {
  1641.                   pos = faces[i][8];
  1642.                   outside_four_flag = true;
  1643.                   face_index = i; 
  1644.                }
  1645.                if (occupied[pos] == 0) {
  1646.                   occupied[pos] = MACHINE;
  1647.                   positions.set(pos, MACHINE);
  1648.                   player = update_logic_arrays(pos);
  1649.                   if (debug) System.out.println("check_outside_four:  true");
  1650.                   return true;  
  1651.                }
  1652.             }
  1653.          }
  1654.       }
  1655.  
  1656.       // Take the corners, if available.
  1657.       for (int i=0; i<18; i++) {
  1658.          if (outside_four[i][0] > 0 &&
  1659.              outside_four[i][1] == MACHINE) {
  1660.             if (faces[i][0] > 0 &&
  1661.                 faces[i][1] == MACHINE) {
  1662.                for (int j=2; j<6; j++) {
  1663.                   pos = outside_four[i][j];
  1664.                   if (occupied[pos] == 0) {
  1665.                      occupied[pos] = MACHINE;
  1666.                      positions.set(pos, MACHINE);
  1667.                      player = update_logic_arrays(pos);
  1668.                      if (debug) System.out.println("check_outside_four:  true");
  1669.                      return true;  
  1670.                   }
  1671.                }
  1672.             }
  1673.          }
  1674.       }
  1675.  
  1676.       // Look for an "outside four" combination in a face in which the 
  1677.       // opponent holds no positions.
  1678.       for (int i=0; i<18; i++) {
  1679.          if (outside_four[i][0] == 0 || (outside_four[i][0] > 0 &&
  1680.              outside_four[i][1] == MACHINE)) {
  1681.  
  1682.             if (outside_four[i][1] == MACHINE)
  1683.                 outside_four_flag = true;
  1684.             for (int j=2; j<6; j++) {
  1685.                pos = outside_four[i][j];
  1686.                if (occupied[pos] == 0) {
  1687.                   occupied[pos] = MACHINE;
  1688.                   positions.set(pos, MACHINE);
  1689.                   player = update_logic_arrays(pos);
  1690.                   if (debug) System.out.println("check_outside_four:  true");
  1691.                   return true;  
  1692.                }
  1693.             }
  1694.          }
  1695.       }
  1696.  
  1697.       if (debug) System.out.println("check_outside_four:  false");
  1698.       return false;
  1699.    }
  1700.  
  1701.  
  1702.    /**
  1703.     *  Take outside four
  1704.     */
  1705.    public boolean take_outside_four() {
  1706.  
  1707.       int pos = 0;
  1708.       boolean found = false; 
  1709.  
  1710.       if (occupied[0] == 0) {
  1711.          found = true; 
  1712.          pos = 0; 
  1713.       }  
  1714.       else if (occupied[3] == 0) {
  1715.          found = true;   
  1716.          pos = 3;   
  1717.       }  
  1718.       else if (occupied[12] == 0) {
  1719.          found = true;   
  1720.          pos = 12;   
  1721.       }  
  1722.       else if (occupied[15] == 0) {
  1723.          found = true;   
  1724.          pos = 15;   
  1725.       }  
  1726.       else if (occupied[48] == 0) {
  1727.          found = true;   
  1728.          pos = 48;  
  1729.       }  
  1730.       else if (occupied[51] == 0) {
  1731.          found = true;   
  1732.          pos = 51;   
  1733.       }  
  1734.       else if (occupied[60] == 0) {
  1735.          found = true;   
  1736.          pos = 60;   
  1737.       }  
  1738.       else if (occupied[63] == 0) {
  1739.          found = true;   
  1740.          pos = 63;
  1741.       }  
  1742.   
  1743.       if (found) { 
  1744.          occupied[pos] = MACHINE;
  1745.          positions.set(pos, MACHINE);
  1746.          player = update_logic_arrays(pos);
  1747.          if (debug) System.out.println("take_outside_four:  true");
  1748.          return true;
  1749.       }
  1750.  
  1751.       if (debug) System.out.println("take_outside_four:  false");
  1752.       return false;
  1753.    }
  1754.  
  1755.  
  1756.    /**
  1757.     *  Check for a forced win by intersecting rows. Block
  1758.     *  if necessary.
  1759.     */
  1760.    public boolean block_intersecting_rows() {
  1761.  
  1762.       int pos;
  1763.  
  1764.       // Loop through each row and check for rows that have two
  1765.       // positions occupied by the human and two positions which are empty.
  1766.       // Make sure that none of the empty positions in this row intersect 
  1767.       // with another row that also contains two positions held by the human. 
  1768.       // If so, block the row by taking the position at the intersection
  1769.       // of these two row.
  1770.  
  1771.       // Loop through each row.
  1772.       for (int i=0; i<76; i++) {
  1773.  
  1774.          // Look for a row that has two positions held by the human. 
  1775.          if (combinations[i][0] == 2  && combinations[i][1] == HUMAN) {
  1776.  
  1777.             if (debug)
  1778.                System.out.println("   row " + i + "has 2 positions occupied by the human");
  1779.  
  1780.             // Mark this row with a flag.
  1781.             combinations[i][6] = 1;
  1782.  
  1783.             // Check each position in the row.
  1784.             for (int j=2; j<6; j++) {
  1785.  
  1786.                // Look for the empty positions in the row.
  1787.                pos = combinations[i][j];
  1788.                if (occupied[pos] == 0) {
  1789.  
  1790.                   // Loop through the rows again.
  1791.                   for (int k=0; k<76; k++) {
  1792.  
  1793.                      if (debug) System.out.println("   row " + k);
  1794.  
  1795.                      // Look for another row that has two positions held
  1796.                      // by the human (and which is unmarked.) modified
  1797.                      if (combinations[k][0] == 2     &&
  1798.                          combinations[k][1] == HUMAN &&
  1799.                          combinations[k][6] == 0)       {
  1800.  
  1801.                         if (debug)
  1802.                            System.out.println("found an intersecting row:   row " + k);
  1803.  
  1804.                         // Check the positions in this row and see if
  1805.                         // any match the position we're looking for. If
  1806.                         // we find a match, grab the position and return.
  1807.                         for (int l=2; l<6; l++) {
  1808.                            if (pos == combinations[k][l]) {
  1809.                               combinations[i][6] = 0;
  1810.                               occupied[pos] = MACHINE;
  1811.                               positions.set(pos, MACHINE);
  1812.                               player = update_logic_arrays(pos);
  1813.                               if (debug) System.out.println("block_intersecting_rows:  true");
  1814.                               return true;
  1815.                            }
  1816.                         }
  1817.                      }
  1818.                   }
  1819.                }
  1820.             }
  1821.  
  1822.             // Unmark the combination before moving on.
  1823.             combinations[i][6] = 0;
  1824.          }
  1825.  
  1826.       }
  1827.       if (debug) System.out.println("block_intersecting_rows:  false");
  1828.       return false;
  1829.    }
  1830.  
  1831.    /**
  1832.     *  Check for a forced win by intersecting rows. Block
  1833.     *  if necessary.
  1834.     */
  1835.    public boolean check_intersecting_rows2() {
  1836.  
  1837.       int pos;
  1838.  
  1839.       // Loop through each row and check for rows that have two
  1840.       // positions occupied by the human and two positions which are empty.
  1841.       // Make sure that none of the empty positions in this row intersect 
  1842.       // with another row that also contains two positions held by the human. 
  1843.       // If so, block the row by taking the position at the intersection
  1844.       // of these two row.
  1845.  
  1846.       // Loop through each row.
  1847.       for (int i=0; i<76; i++) {
  1848.  
  1849.          // Look for a row that has two positions held by the human. 
  1850.          if (combinations[i][0] == 2  && combinations[i][1] == HUMAN) {
  1851.  
  1852.             if (debug) {
  1853.                System.out.println("   row " + i + "has 2 positions occupied by the human");
  1854.             }
  1855.  
  1856.             // Mark this row with a flag.
  1857.             combinations[i][6] = 1;
  1858.  
  1859.             // Check each position in the row.
  1860.             for (int j=2; j<6; j++) {
  1861.  
  1862.                // Look for the empty positions in the row.
  1863.                pos = combinations[i][j];
  1864.                if (occupied[pos] == 0) {
  1865.  
  1866.                   // Loop through the rows again.
  1867.                   for (int k=0; k<76; k++) {
  1868.  
  1869.                      if (debug) System.out.println("   row " + k);
  1870.  
  1871.                      // Look for another row that has two positions held
  1872.                      // by the human (and which is unmarked.) modified
  1873.                      if (combinations[k][0] == 1     &&
  1874.                          combinations[k][1] == HUMAN &&
  1875.                          combinations[k][6] == 0)       {
  1876.  
  1877.                         if (debug)
  1878.                            System.out.println("found an intersecting row:   row " + k);
  1879.  
  1880.                         // Check the positions in this row and see if
  1881.                         // any match the position we're looking for. If
  1882.                         // we find a match, grab the position and return.
  1883.                         for (int l=2; l<6; l++) {
  1884.                            if (pos == combinations[k][l]) {
  1885.                               combinations[i][6] = 0;
  1886.                               occupied[pos] = MACHINE;
  1887.                               positions.set(pos, MACHINE);
  1888.                               player = update_logic_arrays(pos);
  1889.                               if (debug) System.out.println("check_intersecting_rows:  true");
  1890.                               return true;
  1891.                            }
  1892.                         }
  1893.                      }
  1894.                   }
  1895.                }
  1896.             }
  1897.  
  1898.             // Unmark the combination before moving on.
  1899.             combinations[i][6] = 0;
  1900.          }
  1901.  
  1902.       }
  1903.       if (debug) System.out.println("check_intersecting_rows:  false");
  1904.       return false;
  1905.    }
  1906.  
  1907.  
  1908.    /**
  1909.     *  Check for a forced win by intersecting rows. Block
  1910.     *  if necessary.
  1911.     */
  1912.    public boolean check_for_two() {
  1913.  
  1914.       int pos;
  1915.  
  1916.       // Loop through the rows.
  1917.       for (int i=0; i<76; i++) {
  1918.  
  1919.          // Look for a row that has two positions held
  1920.          // by the human (and which is unmarked.)
  1921.          if (combinations[i][0] == 2     &&  
  1922.              combinations[i][1] == HUMAN &&
  1923.              combinations[i][6] == 0)       {
  1924.  
  1925.             // Take the first available spot.
  1926.             for (int j=2; j<6; j++) {
  1927.                pos = combinations[i][j];
  1928.                if (occupied[pos] == 0) {
  1929.                   occupied[pos] = MACHINE;
  1930.                   positions.set(pos, MACHINE);
  1931.                   player = update_logic_arrays(pos);
  1932.                   if (debug) System.out.println("check_for_two:  true");
  1933.                   return true;  
  1934.                }
  1935.             }   
  1936.  
  1937.          }   
  1938.       }   
  1939.       if (debug) System.out.println("check_for_two:  false");
  1940.       return false;
  1941.    }
  1942.  
  1943.    public void undo_move() {
  1944.  
  1945.       // Return if no moves are recorded
  1946.       if (nmoves == 0) return;
  1947.  
  1948.       // Set the undo flag
  1949.       undoFlag = true;
  1950.  
  1951.       // Undo the last two moves
  1952.       positions.clear(moves[--nmoves]);
  1953.       positions.clear(moves[--nmoves]);
  1954.  
  1955.       // Undo the winner flag in the positions object
  1956.       positions.noWinner();
  1957.  
  1958.       // Repaint the 2D canvas.
  1959.       canvas.repaint();
  1960.  
  1961.       // Reset the inside/outside flags
  1962.       inside_four_flag = false;
  1963.       outside_four_flag = false;
  1964.       block_chair_flag = false;
  1965.  
  1966.       // Reset the board
  1967.       for (int i=0; i<64; i++) {
  1968.          occupied[i] = 0;
  1969.       }
  1970.  
  1971.       // Reset the inside/outside arrays
  1972.       for (int i=0; i<18; i++) {
  1973.           inside_four[i][0] = 0;
  1974.           inside_four[i][1] = 0;
  1975.           outside_four[i][0] = 0;
  1976.           outside_four[i][1] = 0;
  1977.       }
  1978.  
  1979.       // Reset the faces array
  1980.       for (int i=0; i<18; i++) {
  1981.           faces[i][0] = 0;
  1982.           faces[i][1] = 0;
  1983.       }
  1984.  
  1985.       // Reset the combinations array
  1986.       for (int i=0; i<76; i++) {
  1987.          combinations[i][0] = 0;
  1988.          combinations[i][1] = 0;
  1989.       }
  1990.  
  1991.       if (nmoves == 0) {
  1992.          undoFlag = false;
  1993.          player = HUMAN;
  1994.          return;
  1995.       }
  1996.  
  1997.       // Update the logic arrays
  1998.       int pos;
  1999.       player = HUMAN;
  2000.       for (int i=0; i<nmoves; i++) {
  2001.          pos = moves[i]; 
  2002.          occupied[pos] = player;
  2003.          player = update_logic_arrays(pos);
  2004.       }
  2005.  
  2006.       // Reset the "best picks" array
  2007.       update_best_picks();
  2008.  
  2009.       // Reset the player and undo flag
  2010.       player = HUMAN;
  2011.       undoFlag = false;
  2012.    }
  2013.  
  2014.    /**
  2015.     *  Update the logic arrays that keep track of positions and status.
  2016.     *  If we have a winner, stop the game.
  2017.     */
  2018.    public int update_logic_arrays(int pos) {
  2019.  
  2020.       // Record the move.
  2021.       if (!undoFlag) {
  2022.          moves[nmoves++] = pos;
  2023.       }
  2024.  
  2025.       // Get the number of combinations that this position has.
  2026.       int num_combinations = pos_to_comb[pos][0];
  2027.  
  2028.       // Go through each combination associated with this position 
  2029.       // and update the status. If we have a winner, stop the game.
  2030.       int comb;
  2031.       for (int j=0; j<num_combinations; j++) {
  2032.          comb = pos_to_comb[pos][j+1];
  2033.          if (combinations[comb][1] != player &&
  2034.              combinations[comb][1] != 0) {
  2035.             combinations[comb][0] = -1;
  2036.          }
  2037.          else {
  2038.             combinations[comb][0]++;
  2039.             if (combinations[comb][0] == 4) {
  2040.                end_time = System.currentTimeMillis();
  2041.                time = (end_time - beg_time)/1000;
  2042.                panel.winner(player, skill_level, nmoves, time);
  2043.                panel.repaint();
  2044.                canvas.repaint();
  2045.                positions.winner();
  2046.                return END;
  2047.             }
  2048.             else {
  2049.                combinations[comb][1] = player;
  2050.             }
  2051.          }      
  2052.       }  
  2053.  
  2054.       // Update the best_picks array.
  2055.       update_best_picks();
  2056.  
  2057.       // Update the inside_four array.
  2058.       for (int i=0; i<18; i++) {
  2059.          for (int j=2; j<6; j++) {
  2060.             if (pos == inside_four[i][j]) {
  2061.                 if (inside_four[i][0] == 0) {
  2062.                    inside_four[i][0] = 1;
  2063.                    inside_four[i][1] = player;
  2064.                 }
  2065.                 else if (inside_four[i][1] == player) {
  2066.                    inside_four[i][0]++;
  2067.                    inside_four[i][1] = player;
  2068.                 }
  2069.                 else {
  2070.                    inside_four[i][0] = -1;
  2071.                 }
  2072.             }
  2073.          }
  2074.       }
  2075.  
  2076.       // Update the outside_four array.
  2077.       for (int i=0; i<18; i++) {
  2078.          for (int j=2; j<6; j++) {
  2079.             if (pos == outside_four[i][j]) {
  2080.                if (outside_four[i][0] == 0) {
  2081.                   outside_four[i][0] = 1;
  2082.                   outside_four[i][1] = player;
  2083.                }
  2084.                else if (outside_four[i][1] == player) {
  2085.                   outside_four[i][0]++;
  2086.                   outside_four[i][1] = player;
  2087.                }
  2088.                else {
  2089.                   outside_four[i][0] = -1;
  2090.                }
  2091.             }
  2092.          }
  2093.       }
  2094.       
  2095.       // Update the faces array.
  2096.       for (int i=0; i<18; i++) {
  2097.          for (int j=2; j<18; j++) {
  2098.             if (pos == faces[i][j]) {
  2099.                if (faces[i][0] == 0) {
  2100.                   faces[i][0] = 1;
  2101.                   faces[i][1] = player;
  2102.                }
  2103.                else if (faces[i][1] == player) {
  2104.                   faces[i][0]++;
  2105.                }
  2106.                else {
  2107.                   faces[i][0] = -1;
  2108.                }
  2109.             }
  2110.          }
  2111.           
  2112.       }
  2113.  
  2114.       // Switch players.
  2115.       if (player == HUMAN)
  2116.          return MACHINE;
  2117.       else
  2118.          return HUMAN;
  2119.    }
  2120.  
  2121.  
  2122.    /**
  2123.     *  Start a new game.
  2124.     */
  2125.    public void newGame() {
  2126.  
  2127.       // Initialize the inside/outside flags.
  2128.       inside_four_flag = false;
  2129.       outside_four_flag = false;
  2130.       block_chair_flag = false;
  2131.  
  2132.       // Initialize the inside/outside arrays.
  2133.       for (int i=0; i<18; i++) {
  2134.           inside_four[i][0] = 0;
  2135.           inside_four[i][1] = 0;
  2136.           outside_four[i][0] = 0;
  2137.           outside_four[i][1] = 0;
  2138.       }
  2139.  
  2140.       // Initialize the faces array.
  2141.       for (int i=0; i<18; i++) {
  2142.           faces[i][0] = 0;
  2143.           faces[i][1] = 0;
  2144.       }
  2145.  
  2146.       // Initialize the board.
  2147.       for (int i=0; i<64; i++) {
  2148.          occupied[i] = 0;
  2149.       }
  2150.       for (int i=0; i<76; i++) {
  2151.          combinations[i][0] = 0;
  2152.          combinations[i][1] = 0;
  2153.       }
  2154.  
  2155.       // Reset the best_picks array.
  2156.       update_best_picks();
  2157.  
  2158.       // Set the player with the first move.
  2159.       player = HUMAN;
  2160.  
  2161.       // Initialize the number of moves.
  2162.       nmoves = 0;
  2163.  
  2164.       // Reset the playing positions.
  2165.       positions.newGame();
  2166.    }
  2167.  
  2168.  
  2169.    /**
  2170.     *  Set the skill level.
  2171.     */
  2172.    public void set_skill_level(int level) {
  2173.       skill_level = level;
  2174.    }
  2175.  
  2176.  
  2177.    /**
  2178.     *  Set up the pos_to_comb array.
  2179.     */
  2180.    public void setup_pos_to_comb() {
  2181.  
  2182.       // Set up the pos_to_comb array to point to every winning
  2183.       // combination a given position may have.
  2184.       int count;
  2185.       for (int i=0; i<64; i++) {
  2186.           count = 1;
  2187.           pos_to_comb[i][0] = 0;
  2188.           for (int j=0; j<76; j++) {
  2189.                 for (int k=2; k<6; k++) {
  2190.                    if (combinations[j][k] == i) {
  2191.                        pos_to_comb[i][0]++;
  2192.                        pos_to_comb[i][count++] = j;
  2193.                    }
  2194.                 }
  2195.           }
  2196.       }
  2197.  
  2198.       if (debug) {
  2199.          for (int i=0; i<64; i++) {
  2200.              System.out.println("");
  2201.              for (int j=0; j<8; j++) {
  2202.                 System.out.println("pos_to_comb[" + i + "][" + j + "] = " + pos_to_comb[i][j]);
  2203.              }
  2204.          }
  2205.       }
  2206.  
  2207.    }
  2208.  
  2209.  
  2210.    /**
  2211.     *  Update the best_picks array.
  2212.     */
  2213.    public void update_best_picks() {
  2214.  
  2215.       // Re-calculate the best_picks array to point to every (current) winning 
  2216.       // combination a given position may have.
  2217.       int count;
  2218.       for (int i=0; i<64; i++) {
  2219.  
  2220.           count = 1;
  2221.           best_picks[i][0] = 0;
  2222.           if (occupied[i] == 0) {
  2223.              for (int j=0; j<76; j++) {
  2224.  
  2225.                 if (combinations[j][0] == 0 ||
  2226.                     combinations[j][1] == MACHINE) {
  2227.  
  2228.                    for (int k=2; k<6; k++) {
  2229.                       if (combinations[j][k] == i) {
  2230.                          best_picks[i][0]++;
  2231.                          best_picks[i][count++] = j;
  2232.                       }
  2233.                    }
  2234.                 }
  2235.              }
  2236.           }
  2237.       }
  2238.  
  2239.       if (debug) {
  2240.          for (int i=0; i<64; i++) {
  2241.              System.out.println("");
  2242.              for (int j=0; j<8; j++) {
  2243.                 System.out.println("best_picks[" + i + "][" + j + "] = " + best_picks[i][j]); 
  2244.              }
  2245.          }
  2246.       }
  2247.    }
  2248.  
  2249.  
  2250.    /**
  2251.     *  Pick the computer's best possible move based on the number
  2252.     *  of combinations per position. Choose the position with the
  2253.     *  most combinations.
  2254.     */
  2255.    public void pick_best_position() {
  2256.  
  2257.       int pos = 0;
  2258.       int max_num = 0;
  2259.       for (int i=0; i<64; i++) {
  2260.          if (best_picks[i][0] > max_num &&
  2261.              occupied[i] == 0) {
  2262.             pos = i;
  2263.             max_num = best_picks[i][0];
  2264.          }
  2265.       }
  2266.  
  2267.       // Mark the position as MACHINE.
  2268.       occupied[pos] = MACHINE;
  2269.  
  2270.       positions.set(pos, MACHINE);
  2271.  
  2272.       // Udate the logic arrays and reset the player.
  2273.       player = update_logic_arrays(pos);
  2274.    }
  2275.  
  2276.  
  2277.    public boolean pick_7() {
  2278.  
  2279.       for (int i=0; i<64; i++) {
  2280.          if (best_picks[i][0] == 7) { 
  2281.             occupied[i] = MACHINE;
  2282.             positions.set(i, MACHINE);
  2283.             player = update_logic_arrays(i);
  2284.             return true;
  2285.          }
  2286.       }
  2287.       return false;
  2288.  
  2289.    }
  2290.   
  2291.    public void change_face() {
  2292.       current_face = ++current_face%18;
  2293.    }
  2294.   
  2295.    public void label() {
  2296.       label_flag ^= true;
  2297.    }
  2298.  
  2299.    public boolean unoccupied(int pos) {
  2300.       if (occupied[pos] == UNOCCUPIED)
  2301.          return true;
  2302.       else
  2303.          return false;
  2304.    } 
  2305. }
  2306.